web-dev-qa-db-ja.com

ANDの代わりにORを使用したMultiDataTrigger

DataTriggersに複数のButtonを設定しようとしています。調査を行ったところ、MultiDataTriggerを使用すると、これを実行できることがわかりました。 CCTVPath == string.Empty OR PermissionsFlag == falseの場合、VisibilityButtonプロパティを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は間違いなくfalseであり、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>
17
CBreeze

代替ソリューションは、MultiBindingで単一のDataTriggerを使用することです。オブジェクト配列に2つの項目があると想定する「特殊なケース」のIMultiValueConverterを定義し、最初の項目が空の文字列である場合にtrueを返すことで機能させることができますOR 2番目の項目がfalseです。ただし、コード内で他の場所でそのコンバーターを使用することはおそらくないでしょう。

1)[IMultiValueConverter] 'OrConverter'。これは次のようになります。

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();
   }
}

2)[IValueConverter] 'IsNullOrEmpty'文字列コンバーター:

public class StringIsNullOrEmptyConverter : IValueConverter {
   public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
      return string.IsNullOrEmpty(value as string);
   }

   public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
      throw new NotImplementedException();
   }
}

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は次のように定義されます。

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

私は、読みやすさのために2つの個別のDataTriggersを使用するよりもこのソリューションを好んでいます。定義している動作をより適切に表現します。これは「または」ロジックです。ボタンを非表示にする2つの条件の1つのセットです。

1
John Colvin