根据视图模型布尔属性(MVVM 体系结构)禁用子视图
本文关键字:视图 体系结构 MVVM 模型 布尔 属性 | 更新日期: 2023-09-27 18:37:25
我有一个包含多个子视图(UserControl)的视图。
<StackPanel>
<local:SubViewGPS/>
<local:SubViewText/>
</StackPanel>
此视图绑定到视图模型,我想根据视图模型的布尔属性加载或不加载子视图
private bool isGPSCompatible;
public bool IsGPSCompatible {
get { return isGPSCompatible; }
set {
if (isGPSCompatible != value) {
isGPSCompatible = value;
NotifyPropertyChanged();
}
}
}
private bool isTextCompatible;
public bool IsTextCompatible {
get { return isTextCompatible; }
set {
if (isTextCompatible != value) {
isTextCompatible = value;
NotifyPropertyChanged();
}
}
}
我实际上不想"禁用"或更改"可见性",但如果属性为 false,我真的要避免加载组件。根据这篇文章:基于成员变量的不同视图/数据模板 DataTemplate 和 DataTrigger 的组合似乎是实现目标的一种方式,但我想知道它是否存在更简单的东西。感谢您的帮助
我终于使用了这个解决方案:
<UserControl x:Class="RLinkClient.LocationView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:client"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<DataTemplate x:Key="GPSLocationViewTemplate">
<local:GPSControl/>
</DataTemplate>
<DataTemplate x:Key="NoGPSViewTemplate">
<TextBlock Text="GPS Disabled" TextAlignment="Center" VerticalAlignment="Center" FontStyle="Italic" Opacity="0.1" FontWeight="Bold" FontSize="14"/>
</DataTemplate>
</UserControl.Resources>
<Grid>
<ContentControl>
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Setter Property="ContentTemplate" Value="{StaticResource NoGPSViewTemplate}" />
<Style.Triggers>
<DataTrigger Binding="{Binding GPSCapable}" Value="True">
<Setter Property="ContentTemplate" Value="{StaticResource GPSLocationViewTemplate}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</Grid>
</UserControl>
但是如果我能改变视图模型结构,坦率的回答是完全可以接受的。
在使用 MVVM 时,您可以为不同的视图创建单独的子视图模型,并根据它们的属性将它们添加到某个 ObservableCollection 中:
<!-- This would replace your StackPanel -->
<ItemsControl ItemsSource="{Binding Capabilities}">
<ItemsControl.Resources>
<DataTemplate DataType="localVm:GpsViewModel">
<local:SubViewGPS />
</DataTemplate>
<DataTemplate DataType="localVm:TextViewModel">
<local:SubViewText />
</DataTemplate>
<!-- ... -->
</ItemsControl.Resources>
</ItemsControl>
您的视图模型中将有一个可观察集合,如下所示:
public ObservableCollection<ICapability> Capabilities { get; private set; }
并根据需要添加实现ICapability
的子视图模型。
根据条件,我建议在代码而不是 XAML 中添加视图对象。仅在需要时实例化以避免不必要的初始化例程。也就是说,在检查条件之前不要实例化视图:
if (IsGPSCompatible )
myStackPanel.Children.Add((new SubViewGPSView()));
if (IsTextCompatible )
myStackPanel.Children.Add((new SubViewText()));