How to bind inverse boolean properties in WPF?

Russ picture Russ · Jun 24, 2009 · Viewed 206.2k times · Source

What I have is an object that has an IsReadOnly property. If this property is true, I would like to set the IsEnabled property on a Button, ( for example ), to false.

I would like to believe that I can do it as easily as IsEnabled="{Binding Path=!IsReadOnly}" but that doesn't fly with WPF.

Am I relegated to having to go through all of the style settings? Just seems too wordy for something as simple as setting one bool to the inverse of another bool.

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

Answer

Chris Nicol picture Chris Nicol · Jun 24, 2009

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
    }