DataTriggers
に複数のButton
を設定しようとしています。調査を行ったところ、MultiDataTrigger
を使用すると、これを実行できることがわかりました。 CCTVPath == string.Empty
OR PermissionsFlag == false
の場合、Visibility
のButton
プロパティを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>
代替ソリューションは、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つのセットです。