Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting 'this' pointer inside dependency property changed callback

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.

like image 319
Mizipzor Avatar asked Mar 16 '10 09:03

Mizipzor


3 Answers

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
    }
}
like image 147
hypehuman Avatar answered Sep 17 '22 06:09

hypehuman


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

like image 20
Catalin DICU Avatar answered Sep 19 '22 06:09

Catalin DICU


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

like image 39
Thomas Levesque Avatar answered Sep 20 '22 06:09

Thomas Levesque