有沒有什麼方法可以聽取DependencyProperty
的更改?我希望收到通知並在值發生變化時執行一些操作,但我無法使用綁定。這是另一類的DependencyProperty
。傾聽依賴屬性的更改
回答
如果是單獨類的DependencyProperty
,最簡單的方法是將值綁定到該值,並監聽該值的更改。
如果DP是您在自己班級中實施的DP,那麼當您創建DependencyProperty
時,您可以register a PropertyChangedCallback。您可以使用它來聆聽屬性的更改。
如果您使用的是子類,則可以使用OverrideMetadata將自己的PropertyChangedCallback
添加到將被調用的DP,而不是任何原始調用。
根據[MSDN](http://msdn.microsoft.com/en-us/library/ms597491.aspx)和我的經驗,_(所提供的元數據的)某些特徵...其他(如PropertyChangedCallback) ._因此,您自己的PropertyChangedCallback將*除現有回調以外的其他*調用*,而不是*。 –
死鏈接?現在是https://msdn.microsoft.com/library/ms745795%28v=vs.100%29.aspx? –
如果是這樣的話,One hack。你可以引入一個帶有DependencyProperty
的靜態類。您的源類也綁定到該dp,並且您的目標類也綁定到DP。
這種方法肯定是缺少在這裏:
DependencyPropertyDescriptor
.FromProperty(RadioButton.IsCheckedProperty, typeof(RadioButton))
.AddValueChanged(radioButton, (s,e) => { /* ... */ });
因爲它可以很容易地引入內存泄漏,所以要非常小心! 總是使用'descriptor.RemoveValueChanged(...)' – CodeMonkey
再次刪除處理程序請參閱http://agsmith.wordpress.com/2008/04/07/propertydescriptor中的詳細信息和替代方法(定義新的依賴項屬性+綁定) -addvaluechanged-alternative/ – Lu55
這適用於WPF(這是這個問題的目的)。如果您在此尋找Windows Store解決方案,則需要使用綁定技巧。發現這篇博文可能有所幫助:http://blogs.msdn.com/b/flaviencharlon/archive/2012/12/07/getting-change-notifications-from-any-dependency-property-in-windows-store- apps.aspx可能也適用於WPF(如上面的答案中所述)。 – Gordon
我寫了這個工具類:
- 它給老&新的價值DependencyPropertyChangedEventArgs。
- 源被存儲在綁定中的弱引用中。
- 不確定是否暴露綁定& BindingExpression是個好主意。
- 沒有泄漏。
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);
}
}
如果綁定是OneWay,爲什麼你要設置UpdateSourceTrigger? – Maslow
@Maslow沒有理由,只是噪音,我會更新,謝謝。 –
你可以繼承你想要聽的控制,然後可以直接獲得:
protected void OnPropertyChanged(string name)
內存泄漏的沒有風險。
不要害怕標準的面向對象技術。
有多種方法可以實現這一點。這裏是一個辦法依賴屬性轉換爲可觀察到的,例如,它可以訂閱到使用System.Reactive:
public static class DependencyObjectExtensions
{
public static IObservable<EventArgs> Observe<T>(this T component, DependencyProperty dependencyProperty)
where T:DependencyObject
{
return Observable.Create<EventArgs>(observer =>
{
EventHandler update = (sender, args) => observer.OnNext(args);
var property = DependencyPropertyDescriptor.FromProperty(dependencyProperty, typeof(T));
property.AddValueChanged(component, update);
return Disposable.Create(() => property.RemoveValueChanged(component, update));
});
}
}
使用
記住處置訂閱防止內存泄漏:
public partial sealed class MyControl : UserControl, IDisposable
{
public MyControl()
{
InitializeComponent();
// this is the interesting part
var subscription = this.Observe(MyProperty)
.Subscribe(args => { /* ... */}));
// the rest of the class is infrastructure for proper disposing
Subscriptions.Add(subscription);
Dispatcher.ShutdownStarted += DispatcherOnShutdownStarted;
}
private IList<IDisposable> Subscriptions { get; } = new List<IDisposable>();
private void DispatcherOnShutdownStarted(object sender, EventArgs eventArgs)
{
Dispose();
}
Dispose(){
Dispose(true);
}
~MyClass(){
Dispose(false);
}
bool _isDisposed;
void Dispose(bool isDisposing)
{
if(_disposed) return;
foreach(var subscription in Subscriptions)
{
subscription?.Dispose();
}
_isDisposed = true;
if(isDisposing) GC.SupressFinalize(this);
}
}
- 1. JavaScript:傾聽屬性更改?
- 2. 屬性更改依賴屬性
- 3. 如何從附加的依賴項屬性中偵聽依賴屬性中的更改?
- 4. 更改WPF依賴項屬性ActualWidth == 0
- 5. 調試依賴屬性更改wpf?
- 6. 在模型的屬性上傾聽具體的值更改
- 7. 如何傾聽對象的屬性更改?
- 8. 依賴屬性 - 更新源
- 9. Ldap:傾聽外部更改
- 10. 依賴屬性
- 11. 依賴屬性
- 12. WPF:CLR屬性依賴屬性
- 13. 不依賴於UserControl的依賴屬性
- 14. 依賴的屬性不會改變
- 15. Silverlight的依賴屬性沒有更新/更改
- 16. 具有子屬性的依賴屬性更新主屬性?
- 17. 依賴於其他屬性的依賴屬性
- 18. 不更新UI的依賴屬性
- 19. 依賴屬性空
- 20. 依賴屬性WPF
- 21. 依賴屬性依賴於另一個
- 22. 如果我的依賴項屬性是一個類,如何將屬性更改爲激活類屬性更改?
- 23. TableView部分更新依賴於CoreData瞬態屬性更改
- 24. DataBound依賴項屬性不會更新源值更改
- 25. 更改數據環境後,依賴項屬性不會更新
- 26. 更改WPF中的依賴項屬性的值
- 27. 綁定依賴屬性到另一個依賴屬性
- 28. 更新依賴屬性當子屬性已更新
- 29. ControlTemplate中的ContentPresenter無法更改附加依賴項屬性
- 30. 如何更改usercontrol內的依賴項屬性值?
爲什麼說你不能使用綁定? –