Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to propagate PropertyChanged changes in DependencyProperty

I have a class which implements INotifyPropertyChanged. An instance of this class is declared as a DependencyProperty in a Window, e.g.,

    public IMyClass MyClass
    {
        get { return (IMyClass)GetValue(MyClassProperty); }
        set { SetValue(MyClassProperty, value); }
    }
    public static readonly DependencyProperty MyClassProperty=
        DependencyProperty.Register("MyClass", typeof(IMyClass), typeof(MainWindow), new UIPropertyMetadata(null));

In the XAML, I have an element which is bound to this class using

Text="{Binding MyClass, Converter={StaticResource someConverter}}

Whenever I change a property in MyClass, I would like someConverter to be triggered. However, it only happens when I completely swap out MyClass. Is there a way to tie DependencyProperty updates to my MyClass PropertyChanged?

Update. In the spirit of AresAvatar's solution, here's what we have so far. The issue remaining is how to call InvalidateProperty (without having MyClass track it...)

    public IMyClass MyClass
    {
        get { return (IMyClass)GetValue(MyClassProperty); }
        set { SetValue(MyClassProperty, value); }
    }
    public static readonly DependencyProperty MyClassProperty =
        DependencyProperty.Register("MyClass", typeof(IMyClass), typeof(MainWindow),
        new UIPropertyMetadata(null, new PropertyChangedCallback(OnMyClassChanged)));

    private static void OnMyClassChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (e.OldValue != null)
        {
            ((IMyClass)e.OldValue).PropertyChanged -= ((MainWindow)d).MyClass_PropertyChanged;
        }

        if (e.NewValue != null)
        {
            ((IMyClass)e.NewValue).PropertyChanged += ((MainWindow)d).MyClass_PropertyChanged;
        }
    }

    private void MyClass_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        this.InvalidateProperty(MyClassProperty);  <----- still does not refresh binding, but called.
    }
like image 409
tofutim Avatar asked Jun 30 '11 22:06

tofutim


1 Answers

Converters should not do more work than simple conversions, your question sounds like the converter uses a lot of properties of the object to create some combined value. Use a MultiBinding instead which hooks into all the different properties on the object you need, that way the MultiValueConverter on that MultiBinding will fire if any of those properties change.

Further, since you seem to create text you might be able to get away without using any converter at all as the StringFormat might be enough.

like image 103
H.B. Avatar answered Nov 10 '22 14:11

H.B.