11

I have the following dependency property inside a class:

class FooHolder
{
    public static DependencyProperty CurrentFooProperty = DependencyProperty.Register(
        "CurrentFoo",
        typeof(Foo), 
        typeof(FooHandler),
        new PropertyMetadata(OnCurrentFooChanged));

    private static void OnCurrentFooChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        FooHolder holder = (FooHolder) d.Property.Owner; // <- something like this

        // do stuff with holder
    }
}

I need to be able to retrieve a reference to the class instance in which the changed property belongs.

This is since FooHolder has some event handlers that needs to be hooked/unhooked when the value of the property is changed. The property changed callback must be static, but the event handler is not.

Mizipzor
  • 51,151
  • 22
  • 97
  • 138

3 Answers3

17

Something like this : (you'll have to define UnwireFoo() and WireFoo() yourself)

private static void OnCurrentFooChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    FooHolder holder = (FooHolder)d; // <- something like this

    holder.UnwireFoo(e.OldValue as Foo);
    holder.WireFoo(e.NewValue as Foo);
}

And, of course, FooHolder must inherit from DependencyObject

Catalin DICU
  • 4,610
  • 5
  • 34
  • 47
  • And here I was looking around the properties *inside* d, maybe it was to obvious. Thanks! – Mizipzor Mar 16 '10 at 10:18
  • 1000 thankes for this one... I just went to a voyage of 16 hours to find the obvious.. MSDN documentation seems to be written by Sir Humphrey Appleby.. – G.Y Feb 27 '13 at 21:39
3

The owner of the property being changed is the d parameter of your callback method

Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
3

Based on @catalin-dicu 's answer, I added this helper method to my library. It felt a bit more natural to have the OnChanged method be non-static and to hide all the casting.

static class WpfUtils
{
    public static DependencyProperty RegisterDependencyPropertyWithCallback<TObject, TProperty>(string propertyName, Func<TObject, Action<TProperty, TProperty>> getOnChanged)
        where TObject : DependencyObject
    {
        return DependencyProperty.Register(
            propertyName,
            typeof(TProperty),
            typeof(TObject),
            new PropertyMetadata(new PropertyChangedCallback((d, e) =>
                getOnChanged((TObject)d)((TProperty)e.OldValue, (TProperty)e.NewValue)
            ))
        );
    }
}

Usage example:

class FooHolder
{
    public static DependencyProperty CurrentFooProperty = WpfUtils.RegisterDependencyPropertyWithCallback
        <FooHolder, Foo>("CurrentFoo", x => x.OnCurrentFooChanged);

    private void OnCurrentFooChanged(Foo oldFoo, Foo newFoo)
    {
        // do stuff with holder
    }
}
hypehuman
  • 1,290
  • 2
  • 18
  • 37