86 lines
2.7 KiB
C#
86 lines
2.7 KiB
C#
using System;
|
|
using System.Windows;
|
|
using System.Windows.Data;
|
|
|
|
namespace TheXamlGuy.UI.WPF
|
|
{
|
|
public class PropertyChangedRevoker : DependencyObject, IDisposable
|
|
{
|
|
public static readonly DependencyProperty ValueProperty =
|
|
DependencyProperty.Register(nameof(Value), typeof(object),
|
|
typeof(PropertyChangedRevoker), new PropertyMetadata(null, OnValuePropertyChanged));
|
|
|
|
private readonly WeakReference weakPropertySource;
|
|
|
|
public PropertyChangedRevoker(DependencyObject propertySource, string path,
|
|
DependencyPropertyChangedEventHandler valueChangedHandler) : this(propertySource, new PropertyPath(path),
|
|
valueChangedHandler)
|
|
{
|
|
}
|
|
|
|
public PropertyChangedRevoker(DependencyObject propertySource, DependencyProperty property,
|
|
DependencyPropertyChangedEventHandler valueChangedHandler) : this(propertySource,
|
|
new PropertyPath(property), valueChangedHandler)
|
|
{
|
|
}
|
|
|
|
public PropertyChangedRevoker(DependencyObject propertySource, PropertyPath property,
|
|
DependencyPropertyChangedEventHandler valueChangedHandler)
|
|
{
|
|
weakPropertySource = new WeakReference(propertySource);
|
|
|
|
Binding binding = new Binding
|
|
{
|
|
Path = property,
|
|
Mode = BindingMode.OneWay,
|
|
Source = propertySource
|
|
};
|
|
|
|
BindingOperations.SetBinding(this, ValueProperty, binding);
|
|
ValueChanged = valueChangedHandler;
|
|
Property = property;
|
|
}
|
|
|
|
public DependencyObject PropertySource
|
|
{
|
|
get
|
|
{
|
|
try
|
|
{
|
|
return weakPropertySource.IsAlive ? weakPropertySource.Target as DependencyObject : null;
|
|
}
|
|
catch
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
|
|
public object Value
|
|
{
|
|
get => GetValue(ValueProperty);
|
|
set => SetValue(ValueProperty, value);
|
|
}
|
|
|
|
public PropertyPath Property { get; }
|
|
|
|
public void Dispose()
|
|
{
|
|
BindingOperations.ClearBinding(this, ValueProperty);
|
|
}
|
|
|
|
private event DependencyPropertyChangedEventHandler ValueChanged;
|
|
|
|
private static void OnValuePropertyChanged(DependencyObject dependencyObject,
|
|
DependencyPropertyChangedEventArgs args)
|
|
{
|
|
PropertyChangedRevoker sender = dependencyObject as PropertyChangedRevoker;
|
|
sender?.OnValuePropertyChanged(args);
|
|
}
|
|
|
|
private void OnValuePropertyChanged(DependencyPropertyChangedEventArgs args)
|
|
{
|
|
ValueChanged?.Invoke(this, args);
|
|
}
|
|
}
|
|
} |