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 开发者_如何学Gois 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.
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
The owner of the property being changed is the d
parameter of your callback method
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
}
}
精彩评论