我有一个包含多个子视图(UserControl)的视图。
<StackPanel>
<local:SubViewGPS/>
<local:SubViewText/>
</StackPanel>
此视图绑定到ViewModel,我想加载或不加载子视图,具体取决于我的ViewModel的bool属性
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,则确实避免加载组件。根据这篇文章:Different views / data template based on member variable 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>
但如果我可以更改ViewModel结构,那么Frank的回答是完全可以接受的。
答案 0 :(得分:1)
当您使用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>
你的视图模型中会有一个ObservableCollection,如下所示:
public ObservableCollection<ICapability> Capabilities { get; private set; }
并根据需要添加实现ICapability
的子视图模型。
答案 1 :(得分:0)
根据条件,我建议在代码中添加视图对象而不是XAML。仅在需要时实例化以避免不必要的初始化例程。也就是说,在检查条件之前不要实例化视图:
if (IsGPSCompatible )
myStackPanel.Children.Add((new SubViewGPSView()));
if (IsTextCompatible )
myStackPanel.Children.Add((new SubViewText()));