How to bind inverse boolean properties in WPF?

I would recommend using https://github.com/JohannesMoersch/QuickConverter

Inverting a boolean is then as simple as: <Button IsEnabled="{qc:Binding '!$P', P={Binding IsReadOnly}}" />

That speeds the time normally needed to write converters.


Have you considered an IsNotReadOnly property? If the object being bound is a ViewModel in a MVVM domain, then the additional property makes perfect sense. If it's a direct Entity model, you might consider composition and presenting a specialized ViewModel of your entity to the form.


With standard bindings you need to use converters that look a little windy. So, I recommend you to look at my project CalcBinding, which was developed specifically to resolve this problem and some others. With advanced binding you can write expressions with many source properties directly in xaml. Say, you can write something like:

<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 viewModel and it will work properly


You can use a ValueConverter that inverts a 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
    }