Есть ли способ прослушать изменения DependencyProperty
? Я хочу получать уведомления и выполнять некоторые действия при изменении значения, но я не могу использовать привязку. Это DependencyProperty
другого класса.Прослушать изменения свойства зависимостей
ответ
Если это DependencyProperty
отдельного класса, самым простым способом является привязка к нему значения и прослушивание изменений этого значения.
Если DP - это тот, который вы реализуете в своем классе, то вы можете register a PropertyChangedCallback при создании DependencyProperty
. Вы можете использовать это, чтобы прослушать изменения свойства.
Если вы работаете с подклассом, вы можете использовать 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 сейчас? –
Если это так, один взлом. Вы можете ввести класс Static с DependencyProperty
. Класс source также привязывается к этому dp, и ваш целевой класс также привязывается к DP.
Этот метод, безусловно, здесь отсутствует:
DependencyPropertyDescriptor
.FromProperty(RadioButton.IsCheckedProperty, typeof(RadioButton))
.AddValueChanged(radioButton, (s,e) => { /* ... */ });
Будьте очень осторожны с этим, так как он может easliy ввести утечки памяти! Всегда удаляйте обработчик снова с помощью 'descriptor.RemoveValueChanged (...)' – CodeMonkey
см. Подробности и альтернативный подход (определение нового свойства зависимостей + привязка) по адресу http://agsmith.wordpress.com/2008/04/07/propertydescriptor -addvaluechanged-alternative/ – Lu55
Это работает для WPF (для чего этот вопрос нужен). Если вы приземляетесь здесь в поисках решения для магазина Windows, вам нужно использовать трюк привязки. Нашли это сообщение в блоге, которое могло бы помочь: 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. Как прослушать изменение значения свойства из usercontrol
- 2. Прослушать изменения трансформации
- 3. Прослушать изменения предпочтений
- 4. Прослушать подробные изменения файла
- 5. Свойства свойства зависимостей PHP
- 6. Как прослушать изменение свойства объекта?
- 7. Прослушать изменения в структуре DOM
- 8. MATLAB прослушать изменения в каталоге
- 9. Swing прослушать изменения макета ребенка
- 10. Приобретенный экземпляр свойства из обратного вызова изменения зависимостей
- 11. DataTrigger не стрельбы при связывании свойства зависимостей изменения
- 12. Использование свойства зависимостей с моделью просмотра для изменения Заливки прямоугольника
- 13. Установите DataContext свойства зависимостей
- 14. Когда использовать свойства зависимостей
- 15. Как работают свойства зависимостей?
- 16. Свойства зависимостей в Silverlight
- 17. Почему свойства зависимостей «статические»?
- 18. WPF свойства зависимостей - игнорируются
- 19. Ошибка свойства зависимостей
- 20. Свойства зависимостей проверки Silverlight
- 21. Свойства зависимостей тестирования устройства
- 22. Maven - задайте свойства зависимостей
- 23. Ошибка свойства зависимостей WPF
- 24. привязок Пользовательские свойства зависимостей
- 25. Логически сочетать свойства зависимостей
- 26. Свойства зависимостей связывания
- 27. Установки свойства зависимостей этого
- 28. Множественные свойства зависимостей
- 29. Свойства зависимостей смешиваются?
- 30. Наследуемые свойства зависимостей
Почему вы говорите, что не можете использовать привязку? –