如何使用数据模板处理多个选项卡的已启用 属性?
How to handle enabled property of multiple tabs using Data Templates?
我有一个带有两个选项卡的 Window,其中包含两个不同的用户控件。为了 enable/disable 导航到第二个选项卡,我从 IPageViewModel
界面在两个 VM 中实现了 IsEnabled
属性。
IsEnabled 布尔值 属性 在 CustomerOrdersViewModel
中通过 Messenger 服务从 CustomerDetailsViewModel
收到 SelectedCustomer
时设置为真。
到目前为止,此方法有效,因为当我 select 来自第一个视图中的数据网格的客户时,第二个选项卡已启用。但问题是当我尝试 select 第一个选项卡返回初始视图时,它是 disabled.
这是特定导航的截屏issue。
我不确定为什么当我使用 Messenger 将 IsEnabled 属性 设置为 true 时,两个选项卡都会被启用。
有人对这里的问题有什么建议吗?
在 CustomerDetailsViewModel
中,我通过 Messenger 发送 selectedCustomer:
private CustomerModel selectedCustomer;
public CustomerModel SelectedCustomer
{
get
{
return selectedCustomer;
}
set
{
selectedCustomer = value;
Messenger.Default.Send<CustomerModel>(selectedCustomer);
RaisePropertyChanged("SelectedCustomer");
}
}
然后在 CustomerDetailsViewModel
中将 IsEnabled 属性 设置为 true,因为 SelectedCustomer 已被传递:
public CustomerOrdersViewModel()
{
Messenger.Default.Register<CustomerModel>(this, OnCustomerReceived);
}
public void OnCustomerReceived(CustomerModel customer)
{
SelectedCustomer = customer;
IsEnabled = true;
}
这是包含两个用户控件的 ApplicationView xaml,以及为每个控件生成的选项卡:
<Window x:Class="MongoDBApp.Views.ApplicationView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:views="clr-namespace:MongoDBApp.Views"
xmlns:vm="clr-namespace:MongoDBApp.ViewModels"
Title="ApplicationView"
Width="800"
Height="500">
<Window.Resources>
<DataTemplate DataType="{x:Type vm:CustomerDetailsViewModel}">
<views:CustomerDetailsView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:CustomerOrdersViewModel}">
<views:CustomerOrdersView />
</DataTemplate>
</Window.Resources>
<Window.DataContext>
<vm:ApplicationViewModel />
</Window.DataContext>
<TabControl ItemsSource="{Binding PageViewModels}"
SelectedItem="{Binding CurrentPageViewModel}"
TabStripPlacement="Top">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ItemContainerStyle>
<Style TargetType="{x:Type TabItem}">
<Setter Property="IsEnabled" Value="{Binding IsEnabled}"/>
</Style>
</TabControl.ItemContainerStyle>
</TabControl>
</Window>
我假设您将新的 ViewModel(CustomerDetails 或 CustomerOrders)分配给 CurrentPageViewModel。每当您这样做时,都会创建一个 class 的新对象,默认情况下 IsEnabled 设置为 false。
解决方法是在与您的视图 (ApplicationViewModel) 关联的 ViewModel 中创建 IsEnabled 属性。然后在ItemContrainerStyle中引用如下:
<Setter Property="IsEnabled" Value="{Binding RelativeSource={RelativeSource AncestoryType=Window}, Path=DataContext.IsEnabled}"/>
TabControlPages 的 ViewModel 中既不需要 IsEnabled 也不需要 Messages,因为您的 IsEnabled 属性 驻留在主 ViewModel 中,两个 TabPages 都引用它。
编辑
过了一会儿,我意识到默认情况下它会被禁用,因为 IsDefault 一开始就等于 false。这很复杂,因为您没有显式创建 TabPage。我附上了完整的解决方案,看看
here.
为什么不直接将 CustomerDetailsViewModel
的 IsEnabled
属性 默认为 true?
这是一个应该始终启用的选项卡,所以这对我来说最有意义。
我有一个带有两个选项卡的 Window,其中包含两个不同的用户控件。为了 enable/disable 导航到第二个选项卡,我从 IPageViewModel
界面在两个 VM 中实现了 IsEnabled
属性。
IsEnabled 布尔值 属性 在 CustomerOrdersViewModel
中通过 Messenger 服务从 CustomerDetailsViewModel
收到 SelectedCustomer
时设置为真。
到目前为止,此方法有效,因为当我 select 来自第一个视图中的数据网格的客户时,第二个选项卡已启用。但问题是当我尝试 select 第一个选项卡返回初始视图时,它是 disabled.
这是特定导航的截屏issue。
我不确定为什么当我使用 Messenger 将 IsEnabled 属性 设置为 true 时,两个选项卡都会被启用。
有人对这里的问题有什么建议吗?
在 CustomerDetailsViewModel
中,我通过 Messenger 发送 selectedCustomer:
private CustomerModel selectedCustomer;
public CustomerModel SelectedCustomer
{
get
{
return selectedCustomer;
}
set
{
selectedCustomer = value;
Messenger.Default.Send<CustomerModel>(selectedCustomer);
RaisePropertyChanged("SelectedCustomer");
}
}
然后在 CustomerDetailsViewModel
中将 IsEnabled 属性 设置为 true,因为 SelectedCustomer 已被传递:
public CustomerOrdersViewModel()
{
Messenger.Default.Register<CustomerModel>(this, OnCustomerReceived);
}
public void OnCustomerReceived(CustomerModel customer)
{
SelectedCustomer = customer;
IsEnabled = true;
}
这是包含两个用户控件的 ApplicationView xaml,以及为每个控件生成的选项卡:
<Window x:Class="MongoDBApp.Views.ApplicationView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:views="clr-namespace:MongoDBApp.Views"
xmlns:vm="clr-namespace:MongoDBApp.ViewModels"
Title="ApplicationView"
Width="800"
Height="500">
<Window.Resources>
<DataTemplate DataType="{x:Type vm:CustomerDetailsViewModel}">
<views:CustomerDetailsView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:CustomerOrdersViewModel}">
<views:CustomerOrdersView />
</DataTemplate>
</Window.Resources>
<Window.DataContext>
<vm:ApplicationViewModel />
</Window.DataContext>
<TabControl ItemsSource="{Binding PageViewModels}"
SelectedItem="{Binding CurrentPageViewModel}"
TabStripPlacement="Top">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ItemContainerStyle>
<Style TargetType="{x:Type TabItem}">
<Setter Property="IsEnabled" Value="{Binding IsEnabled}"/>
</Style>
</TabControl.ItemContainerStyle>
</TabControl>
</Window>
我假设您将新的 ViewModel(CustomerDetails 或 CustomerOrders)分配给 CurrentPageViewModel。每当您这样做时,都会创建一个 class 的新对象,默认情况下 IsEnabled 设置为 false。
解决方法是在与您的视图 (ApplicationViewModel) 关联的 ViewModel 中创建 IsEnabled 属性。然后在ItemContrainerStyle中引用如下:
<Setter Property="IsEnabled" Value="{Binding RelativeSource={RelativeSource AncestoryType=Window}, Path=DataContext.IsEnabled}"/>
TabControlPages 的 ViewModel 中既不需要 IsEnabled 也不需要 Messages,因为您的 IsEnabled 属性 驻留在主 ViewModel 中,两个 TabPages 都引用它。
编辑
过了一会儿,我意识到默认情况下它会被禁用,因为 IsDefault 一开始就等于 false。这很复杂,因为您没有显式创建 TabPage。我附上了完整的解决方案,看看
here.
为什么不直接将 CustomerDetailsViewModel
的 IsEnabled
属性 默认为 true?
这是一个应该始终启用的选项卡,所以这对我来说最有意义。