Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用或代替AND的MultiDataTrigger_C#_Wpf_Xaml_Button_Visibility - Fatal编程技术网

C# 使用或代替AND的MultiDataTrigger

C# 使用或代替AND的MultiDataTrigger,c#,wpf,xaml,button,visibility,C#,Wpf,Xaml,Button,Visibility,我正在尝试在我的按钮上设置多个数据触发器。我做了一些研究,发现MultiDataTrigger允许您这样做。如果CCTVPath==string.Empty或PermissionsFlag==false,我希望将我的按钮的可见性属性设置为false。这就是我目前所拥有的 <Button Grid.Column="3" x:Name="cctvFeedButton" Content="Live Feed" Width="100" FontSize="16" Horizonta

我正在尝试在我的
按钮上设置多个
数据触发器
。我做了一些研究,发现
MultiDataTrigger
允许您这样做。如果
CCTVPath==string.Empty
PermissionsFlag==false,我希望将我的
按钮的
可见性
属性设置为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
肯定是假的,并且肯定是空的
CCTVPath
,但是
按钮从来没有隐藏过。我做错了什么

更新:

    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>

将条件转换为两个独立的数据触发器

<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>
窗口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>

另一种解决方案是将单个数据触发器与多绑定一起使用。您可以通过定义一个“特殊情况”IMultiValueConverter使其工作,该IMultiValueConverter假定对象数组中有2项,如果第一项为空字符串或第二项为false,则返回true。但是,您可能永远不会在代码中的任何其他地方使用该转换器。因此,如果您愿意在前面做更多的工作,您可以定义3个简单/可重用的转换器

1) [IMultiValueConverter]“或Converter”,看起来像这样:

public class BooleanOrConverter : IMultiValueConverter {
   public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) {
      return values.OfType<bool>().Any(b => b);
   }

   public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) {
      throw new NotImplementedException();
   }
}
<Button x:Name="cctvFeedButton" Content="Live Feed"
  Width="100" FontSize="16" HorizontalAlignment="Right" Margin="5">
  <Button.Style>
    <Style TargetType="Button">
      <Style.Triggers>
         <DataTrigger Value="True">
           <DataTrigger.Binding>
             <MultiBinding Converter="{StaticResource OrConverter}">
               <Binding Path="PermissionFlag" Converter="{StaticResource NotConverter}"/>
               <Binding Path="CCTVPath" Converter="{StaticResource IsNullOrEmptyConverter}"/>
             </MultiBinding>
           </DataTrigger.Binding>
           <Setter Property="Visibility" Value="Hidden"/>
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </Button.Style>
</Button>
3) 和[IValueConverter]“NotConverter:”

public class BooleanNotConverter : IValueConverter {
   public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
      return !(bool)value;
   }

   public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
      throw new NotImplementedException();
   }
}
然后,在xaml中,DataTrigger的定义如下:

public class BooleanOrConverter : IMultiValueConverter {
   public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) {
      return values.OfType<bool>().Any(b => b);
   }

   public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) {
      throw new NotImplementedException();
   }
}
<Button x:Name="cctvFeedButton" Content="Live Feed"
  Width="100" FontSize="16" HorizontalAlignment="Right" Margin="5">
  <Button.Style>
    <Style TargetType="Button">
      <Style.Triggers>
         <DataTrigger Value="True">
           <DataTrigger.Binding>
             <MultiBinding Converter="{StaticResource OrConverter}">
               <Binding Path="PermissionFlag" Converter="{StaticResource NotConverter}"/>
               <Binding Path="CCTVPath" Converter="{StaticResource IsNullOrEmptyConverter}"/>
             </MultiBinding>
           </DataTrigger.Binding>
           <Setter Property="Visibility" Value="Hidden"/>
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </Button.Style>
</Button>


为了可读性,我更喜欢这个解决方案,而不是使用两个单独的DataTrigger;它更好地表达了您正在定义的行为-它是“或”逻辑:一组由2个条件组成的单一条件,应该隐藏按钮。

谢谢您的时间。当我这样做时,即使当
PermissionsFlag==false
按钮仍会显示时,我希望无论CCTVPath的值是多少,它都会被隐藏。我希望出现一些错误,就像我删除了
CCTVPath
数据触发器一样,然后它再次不起我想要的作用。我可以在其中添加一个方法来实现这一点,还是需要一个全新的类来引发事件?你手头有好的例子吗?在页面的
onload
方法中,我使用
DataContext=this
PermissionsFlag
仅在页面内使用
public bool PermissionsFlag{get;set;}
OnPropertyChanged(“PermissionsFlag”)更改属性(“\u permissionsFlag”)?这是否也意味着我需要更改
我已经更新了我的问题,你能看到代码有什么问题吗?(它仍然没有隐藏
按钮
<Button x:Name="cctvFeedButton" Content="Live Feed"
  Width="100" FontSize="16" HorizontalAlignment="Right" Margin="5">
  <Button.Style>
    <Style TargetType="Button">
      <Style.Triggers>
         <DataTrigger Value="True">
           <DataTrigger.Binding>
             <MultiBinding Converter="{StaticResource OrConverter}">
               <Binding Path="PermissionFlag" Converter="{StaticResource NotConverter}"/>
               <Binding Path="CCTVPath" Converter="{StaticResource IsNullOrEmptyConverter}"/>
             </MultiBinding>
           </DataTrigger.Binding>
           <Setter Property="Visibility" Value="Hidden"/>
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </Button.Style>
</Button>