有一种方法可以通过使用DataTriggers来完成您所说的工作。
首先,定义一个Style
,其中包含您要使用的DataTrigger
。例如,这里需要注意的两个相同的风格为ContentControl
,每一个DataTrigger
对执行其它的反面:
<Window.Resources>
<Style TargetType="{x:Type ContentControl}" x:Key="HiddenWhenFalse" >
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Value="False" Binding="{Binding MyBooleanValue}">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
<DataTrigger Value="True" Binding="{Binding MyBooleanValue}">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
<Style TargetType="{x:Type ContentControl}" x:Key="HiddenWhenTrue" >
<Setter Property="Visibility" Value="Visible"/>
<Style.Triggers>
<DataTrigger Value="True" Binding="{Binding MyBooleanValue}">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
<DataTrigger Value="False" Binding="{Binding MyBooleanValue}">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
然后,在你的主视觉树中,您将定义ContentControl
S的使用这些Style
S,并将Window
或UserControl
的DataContext
分配给您的ViewModel。事情是这样的:
<Grid>
<StackPanel >
<Button Content="False" Name="Button2"></Button>
<Button Content="True" Name="Button1"></Button>
<ContentControl Style="{StaticResource HiddenWhenFalse}">
<ContentControl.Content>
<TextBlock Text="ITS ALL TRUE"/>
</ContentControl.Content>
</ContentControl>
<ContentControl Style="{StaticResource HiddenWhenTrue}">
<ContentControl.Content>
<TextBlock Text="ITS ALL FALSE"/>
</ContentControl.Content>
</ContentControl>
</StackPanel>
</Grid>
这里是我使用,注意INotifyPropertyChanged的实施视图模型:
Imports System.ComponentModel
Public Class MainWindowViewModel
Implements INotifyPropertyChanged
Private _MyBooleanValue = False
Public Property MyBooleanValue
Get
Return _MyBooleanValue
End Get
Set(ByVal value)
_MyBooleanValue = value
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(Nothing))
End Set
End Property
Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
End Class
现在,这个样本的目的,我只是用导线连接了两个按钮设置ViewModel值。如果你想使用Commands来连接按钮,这是一个完全不同的主题。这是值得讨论的,但是为了简单起见:
Class MainWindow
Private vm As New MainWindowViewModel
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click
vm.MyBooleanValue = True
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button2.Click
vm.MyBooleanValue = False
End Sub
Private Sub MainWindow_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
Me.DataContext = vm
End Sub
End Class
请记住这个样本明确风格ContentControl
,那你必须改变你的风格的TargetType的,如果你用工作类型那不是那个阶级的后裔。
你为什么要这么做? 简而言之,“对XAML进行所有更改”的指导原则可能对您没有意义。我会提供一个代码示例,但如果它看起来比你完全理解的东西更加复杂或者更难以维护,那么你会对自己造成伤害。 – 2010-10-05 22:40:57
我对WPF还比较陌生,正在习惯什么可以被认为是“最佳实践”......我看了一个教程,展示了WPF中的MVVM模式,其中出现的部分原因是背后的代码应该几乎被剥离...如果你做得对,你的视图应该几乎完全是XAML,并且你的ViewModel应该与视图代码分离...所以基本上我正在探索不同的方法来组合一个接口可能会根据用户输入而改变。 – tbischel 2010-10-05 23:21:37
我知道他们在说什么。但是,我遇到的每位顾问都将这些事情放入实际实践中,对这一想法不可知论进行报道。在我看来,它的开发旨在促进将Expression Blend出售给非常大型组织中的混合设计师/开发团队。 也许这种做法最适合在这些地方以团队为基础的筒仓项目。但对于业务线应用程序,它可能是一个巨大的分心。 但是我会给它这么多,你会学习复杂的XAML标记。但不要相信,如果它是XAML,那不是代码。这都是代码。 – 2010-10-05 23:33:32