我想在我的Button上设置多个DataTriggers.我做了一些研究,发现MultiDataTrigger允许你这样做.如果CCTVPath == string.Empty OR PermissionsFlag == false,我希望我的Button的Visibility属性设置为false.这就是我到目前为止所拥有的;
<Button Grid.Column="3" x:Name="cctvFeedButton" Content="Live Feed" Width="100" FontSize="16" HorizontalAlignment="Right" Margin="5" Click="OnCCTVButtonClick"> <Button.Style> <Style TargetType="Button"> <Style.Triggers> <MultiDataTrigger> <MultiDataTrigger.Conditions> <Condition Binding="{Binding CCTVPath}" Value=""/> <Condition Binding="{Binding PermissionsFlag}" Value="False"/> </MultiDataTrigger.Conditions> <Setter Property="Visibility" Value="Hidden"/> </MultiDataTrigger> </Style.Triggers> </Style> </Button.Style> </Button>
在我的代码隐藏中,我设置PermissionsFlag就像这样;
public bool PermissionsFlag { get; set; } private void OnPageLoaded(object sender,RoutedEventArgs e) { PermissionsFlag = false; }
正如你所看到的PermissionsFlag肯定是假的,并且肯定是空CCTVPath但是Button永远不会被隐藏.我究竟做错了什么?
更新:
public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this,new PropertyChangedEventArgs(propertyName)); } private bool _permissionsFlag; public bool Flag { get { return _permissionsFlag; } set { _permissionsFlag = value; OnPropertyChanged("PermissionsFlag"); } } private void OnPageLoaded(object sender,RoutedEventArgs e) { Flag = false; CCTVImageCollection = GetImages(); imageListBox.ItemsSource = CCTVImageCollection; DataContext = this; }
在我的XAML中:
<Button.Style> <Style TargetType="Button"> <Style.Triggers> <DataTrigger Binding="{Binding PermissionsFlag}" Value="False"> <Setter Property="Visibility" Value="Hidden"/> </DataTrigger> </Style.Triggers> </Style> </Button.Style>
解决方法
将条件转换为两个独立的DataTriggers
<Style.Triggers> <DataTrigger Binding="{Binding CCTVPath}" Value=""> <Setter Property="Visibility" Value="Hidden"/> </DataTrigger> <DataTrigger Binding="{Binding PermissionsFlag}" Value="False"> <Setter Property="Visibility" Value="Hidden"/> </DataTrigger> </Style.Triggers>
确保绑定路径正确(检查VS Output窗口是否有可能的异常消息)
另外:不要只依赖Button的隐藏状态,在代码中正确实现权限(OnCCTVButtonClick).在这里阅读原因:
How to Snoop proof your wpf application?
auto-property PermissionsFlag(public bool PermissionsFlag {get; set;})不会通知视图有关更改.
可以实现INotifyPropertyChanged接口(在我的测试窗口中它是这样完成的:公共部分类Window3:Window,INotifyPropertyChanged)然后在属性更改时引发事件.
这是一个完整的工作示例,我用于测试
public partial class Window3 : Window,INotifyPropertyChanged { public Window3() { InitializeComponent(); this.DataContext = this; //PermissionsFlag = true; CCTVPath = "youtube.com"; } private bool _permissionsFlag = false; private string _cctvPath; public bool PermissionsFlag { get { return _permissionsFlag; } set { _permissionsFlag = value; OnPropertyChanged("PermissionsFlag"); } } public string CCTVPath { get { return _cctvPath; } set { _cctvPath = value; OnPropertyChanged("CCTVPath"); } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) PropertyChanged(this,new PropertyChangedEventArgs(propertyName)); } }
窗口xaml:
<Window x:Class="WpfDemos.Views.Window3" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window3" Height="300" Width="300"> <StackPanel> <CheckBox Name="chkPermissionsFlag" Content="PermissionsFlag" IsChecked="{Binding Path=PermissionsFlag,UpdateSourceTrigger=PropertyChanged}"/> <TextBox Text="{Binding Path=CCTVPath,UpdateSourceTrigger=PropertyChanged}"/> <Button x:Name="cctvFeedButton" Content="Live Feed" Width="100" FontSize="16" HorizontalAlignment="Right" Margin="5"> <Button.Style> <Style TargetType="Button"> <Style.Triggers> <DataTrigger Binding="{Binding Path=CCTVPath}" Value=""> <Setter Property="Visibility" Value="Hidden"/> </DataTrigger> <DataTrigger Binding="{Binding Path=PermissionsFlag}" Value="False"> <Setter Property="Visibility" Value="Hidden"/> </DataTrigger> </Style.Triggers> </Style> </Button.Style> </Button> </StackPanel> </Window>