如果它是一个单独类的DependencyProperty,最简单的方法是将一个值绑定到它,并侦听该值的更改。 如果DP是您在自己的类中实现的,那么您可以在创建DependencyProperty时使用register a PropertyChangedCallback。您可以使用它来监听属性的更改。 如果你正在使用一个子类,你可以使用OverrideMetadata将你自己的PropertyChangedCallback添加到将要被调用的DP中,而不是任何原始的DP。
using System;
using System.Collections.Concurrent;
using System.Windows;
using System.Windows.Data;
public sealed class DependencyPropertyListener : DependencyObject, IDisposable
{
private static readonly ConcurrentDictionary<DependencyProperty, PropertyPath> Cache = new ConcurrentDictionary<DependencyProperty, PropertyPath>();
private static readonly DependencyProperty ProxyProperty = DependencyProperty.Register(
"Proxy",
typeof(object),
typeof(DependencyPropertyListener),
new PropertyMetadata(null, OnSourceChanged));
private readonly Action<DependencyPropertyChangedEventArgs> onChanged;
private bool disposed;
public DependencyPropertyListener(
DependencyObject source,
DependencyProperty property,
Action<DependencyPropertyChangedEventArgs> onChanged = null)
: this(source, Cache.GetOrAdd(property, x => new PropertyPath(x)), onChanged)
{
}
public DependencyPropertyListener(
DependencyObject source,
PropertyPath property,
Action<DependencyPropertyChangedEventArgs> onChanged)
{
this.Binding = new Binding
{
Source = source,
Path = property,
Mode = BindingMode.OneWay,
};
this.BindingExpression = (BindingExpression)BindingOperations.SetBinding(this, ProxyProperty, this.Binding);
this.onChanged = onChanged;
}
public event EventHandler<DependencyPropertyChangedEventArgs> Changed;
public BindingExpression BindingExpression { get; }
public Binding Binding { get; }
public DependencyObject Source => (DependencyObject)this.Binding.Source;
public void Dispose()
{
if (this.disposed)
{
return;
}
this.disposed = true;
BindingOperations.ClearBinding(this, ProxyProperty);
}
private static void OnSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var listener = (DependencyPropertyListener)d;
if (listener.disposed)
{
return;
}
listener.onChanged?.Invoke(e);
listener.OnChanged(e);
}
private void OnChanged(DependencyPropertyChangedEventArgs e)
{
this.Changed?.Invoke(this, e);
}
}
using System;
using System.Windows;
public static class Observe
{
public static IDisposable PropertyChanged(
this DependencyObject source,
DependencyProperty property,
Action<DependencyPropertyChangedEventArgs> onChanged = null)
{
return new DependencyPropertyListener(source, property, onChanged);
}
}
6条答案
按热度按时间wwtsj6pe1#
这里肯定缺少这个方法:
注意:因为
DependencyPropertyDescriptor
有一个应用程序中所有处理程序的静态列表,如果处理程序最终没有被删除,那么这些处理程序中引用的每个对象都将泄漏。(它的工作方式与示例对象上的常见事件不同。)总是使用
descriptor.RemoveValueChanged(...)
再次删除处理程序。u7up0aaq2#
如果它是一个单独类的
DependencyProperty
,最简单的方法是将一个值绑定到它,并侦听该值的更改。如果DP是您在自己的类中实现的,那么您可以在创建
DependencyProperty
时使用register a PropertyChangedCallback。您可以使用它来监听属性的更改。如果你正在使用一个子类,你可以使用OverrideMetadata将你自己的
PropertyChangedCallback
添加到将要被调用的DP中,而不是任何原始的DP。n7taea2i3#
我写了这个工具类:
z9gpfhce4#
您可以继承您尝试监听的Control,然后直接访问:
没有内存泄漏的风险。
不要害怕标准的OO技术。
ybzsozfc5#
有多种方法可以实现这一点。下面是一种将依赖属性转换为可观察对象的方法,这样就可以使用System.Reactive订阅它:
用法
请记住释放订阅以防止内存泄漏:
ffvjumwh6#
如果是这样的话,一个黑客。你可以用
DependencyProperty
引入一个Static类。你的源类也绑定到那个DP,你的目标类也绑定到DP。