30

Is there any way to change the value of property at runtime in WPF data binding. Let's say my TextBox is bind to a IsAdmin property. Is there anyway I can change that property value in XAML to be !IsAdmin.

I just want to negate the property so Valueconverter might be an overkill!

NOTE: Without using ValueConverter

Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
azamsharp
  • 19,710
  • 36
  • 144
  • 222

4 Answers4

44

You can use an IValueConverter.

[ValueConversion(typeof(bool), typeof(bool))]
public class InvertBooleanConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        bool original = (bool)value;
        return !original;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        bool original = (bool)value;
        return !original;
    }
}

Then you'd setup your binding like:

<TextBlock Text="{Binding Path=IsAdmin, Converter={StaticResource boolConvert}}" />

Add a resource (usually in your UserControl/Window) like so:

<local:InvertBooleanConverter  x:Key="boolConvert"/>

Edit in response to comment:

If you want to avoid a value converter for some reason (although I feel that it's the most appropriate place), you can do the conversion directly in your ViewModel. Just add a property like:

public bool IsRegularUser
{
     get { return !this.IsAdmin; }
}

If you do this, however, make sure your IsAdmin property setter also raises a PropertyChanged event for "IsRegularUser" as well as "IsAdmin", so the UI updates accordingly.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • Actually I should have mentioned without using ValueConverter – azamsharp Apr 05 '10 at 19:09
  • 9
    Don't you think that is waaaaay to much work for a simple negation operation! – azamsharp Apr 05 '10 at 19:13
  • 10
    @azamsharp: I edited to give you another option - but no, I don't, mainly because it's **reusable** code. Once you make the converter, you can use it for ALL of your !bool conversions, anywhere in your codebase. – Reed Copsey Apr 05 '10 at 19:13
  • 2
    For the valueconverter, here are the namespaces you'll need to use: `using System.Windows.Data; using System.Globalization;` – hereiam Jul 22 '15 at 14:12
  • If you are working with a ``, don't forget to put your resource declaration inside a `` element. – Peter Gluck Jan 18 '23 at 01:16
2

If you specifically want to do this at XAML end (I am not sure the reason for that, unless you have 100s of similar operation of negate) there are only two ways 1) Using IValueConverter 2)write a XAML Markup Extension (Way too much work for this small task :))

Then the other obvious way is to write another property in your ViewModel , which can return the Negative of the IsAdmin property.

Jobi Joy
  • 49,102
  • 20
  • 108
  • 119
0

You can write a ValueConverter that automatically negates the input before returning it. Have a look at BenCon's blog for a short reading on value converters.

StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
Sascha
  • 10,231
  • 4
  • 41
  • 65
0

You can't bind to !Property, but you could create a new Binding with an appropriate IValueConverter and change out the entire Binding at runtime. The key is the BindingOperations class, which allows you to change the binding on a particular DependencyProperty.

    public static void InvertBinding(DependencyObject target, DependencyProperty dp)
    {
        //We'll invert the existing binding, so need to find it
        var binding = BindingOperations.GetBinding(target, dp);
        if (binding != null)
        {
            if (binding.Converter != null)
                throw new InvalidOperationException("This binding already has a converter and cannot be inverted");
            binding.Converter = new InvertingValueConverter(); //This would be your custom converter

            //Not sure if you need this step, but it will cause the binding to refresh
            BindingOperations.SetBinding(target, dp, binding);
        }
    }

This should give you a general idea; I wouldn't use this for production code, as you'd probably want to generalize it to toggle the converter or whatever else you need to change out at runtime. You could also avoid changing the binding entirely by creating a new property you bind to that encapsulates this 'switching' logic. The last option is probably the best.

Dan Bryant
  • 27,329
  • 4
  • 56
  • 102