How to bind an anti Boolean property in WPF?

Keywords: Windows

What I have is an object with the IsReadOnly property. If this property is true, I want to set the IsEnabled property on the Button (for example) to false.

I want to believe that I can do this as easily as isenabled '{binding path =! IsReadOnly}', but it doesn't apply to WPF.

Do I have to go through all the style settings? It seems too long for something as simple as setting one bool to the opposite of another.

<Button.Style>
    <Style TargetType="{x:Type Button}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=IsReadOnly}" Value="True">
                <Setter Property="IsEnabled" Value="False" />
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=IsReadOnly}" Value="False">
                <Setter Property="IsEnabled" Value="True" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Button.Style>

#1 building

You can use ValueConverter to reverse the bool property for you.

XAML:

IsEnabled="{Binding Path=IsReadOnly, Converter={StaticResource InverseBooleanConverter}}"

Converter:

[ValueConversion(typeof(bool), typeof(bool))]
    public class InverseBooleanConverter: IValueConverter
    {
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
        {
            if (targetType != typeof(bool))
                throw new InvalidOperationException("The target must be a boolean");

            return !(bool)value;
        }

        public object ConvertBack(object value, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
        {
            throw new NotSupportedException();
        }

        #endregion
    }

#2 building

Have you considered the IsNotReadOnly property? Additional properties make sense if the bound object is a ViewModel in the MVVM domain. If it is a direct entity model, you can consider combining and rendering the entity's dedicated ViewModel to the form.

#3 building

I suggest using https://quickconverter.codeplex.com/

Then reverse the Boolean as simple as this: < button isenabled = "{QC: binding '! $p', P = {binding isReadOnly}" / >

This speeds up the time it usually takes to write a converter.

#4 building

With standard binding, you need to use a converter that looks windy. Therefore, I suggest you view my project CalcBinding , which was developed specifically to solve this problem. With advanced binding, you can write expressions with many source properties directly in xaml. Say, you can write:

<Button IsEnabled="{c:Binding Path=!IsReadOnly}" />

Or

<Button Content="{c:Binding ElementName=grid, Path=ActualWidth+Height}"/>

Or

<Label Content="{c:Binding A+B+C }" />

Or

<Button Visibility="{c:Binding IsChecked, FalseToVisibility=Hidden}" />

Where A, B, C, ischecked - properties of the ViewModel, which will work properly

Good luck!

#5 building

I don't know if this is related to XAML, but in my simple Windows application, I manually created a binding and added a Format event handler.

public FormMain() {
  InitializeComponent();

  Binding argBinding = new Binding("Enabled", uxCheckBoxArgsNull, "Checked", false, DataSourceUpdateMode.OnPropertyChanged);
  argBinding.Format += new ConvertEventHandler(Binding_Format_BooleanInverse);
  uxTextBoxArgs.DataBindings.Add(argBinding);
}

void Binding_Format_BooleanInverse(object sender, ConvertEventArgs e) {
  bool boolValue = (bool)e.Value;
  e.Value = !boolValue;
}

Posted by TutorMe on Wed, 04 Mar 2020 19:56:55 -0800