Created
September 13, 2016 07:35
-
-
Save AtsushiSuzuki/2248f366c69709efafc723b9d1c49840 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Windows; | |
using System.Windows.Data; | |
namespace WpfApplication1 | |
{ | |
public class DependencyPropertyTracker : DependencyObject | |
{ | |
public object Value | |
{ | |
get { return (object)this.GetValue(DependencyPropertyTracker.ValueProperty); } | |
set { this.SetValue(DependencyPropertyTracker.ValueProperty, value); } | |
} | |
public static readonly DependencyProperty ValueProperty = | |
DependencyProperty.Register(nameof(Value), typeof(object), typeof(DependencyPropertyTracker), new PropertyMetadata(default(object), OnValueChanged)); | |
public event DependencyPropertyChangedEventHandler ValueChanged; | |
private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) | |
{ | |
((DependencyPropertyTracker)d).ValueChanged?.Invoke(d, e); | |
} | |
public DependencyPropertyTracker(BindingBase binding) | |
{ | |
this.BindProperty(binding); | |
} | |
public DependencyPropertyTracker(object source, string path) | |
{ | |
this.BindProperty(new Binding() | |
{ | |
Source = source, | |
Path = new PropertyPath(path), | |
Mode = BindingMode.OneWay, | |
}); | |
} | |
private void BindProperty(BindingBase binding) | |
{ | |
BindingOperations.SetBinding(this, DependencyPropertyTracker.ValueProperty, binding); | |
} | |
public void AddEventHandler(string eventName, Delegate handler) | |
{ | |
this.ValueChanged += (s, e) => | |
{ | |
if (e.OldValue != null) | |
{ | |
this.RemoveEventHandler(e.OldValue, eventName, handler); | |
} | |
if (e.NewValue != null) | |
{ | |
this.AddEventHandler(e.NewValue, eventName, handler); | |
} | |
}; | |
if (this.Value != null) | |
this.AddEventHandler(this.Value, eventName, handler); | |
} | |
private void AddEventHandler( | |
object value, | |
string eventName, | |
Delegate handler) | |
{ | |
if (value == null) | |
{ | |
throw new ArgumentNullException("value"); | |
} | |
var type = value.GetType(); | |
var ei = type.GetEvent(eventName); | |
if (ei == null) | |
{ | |
throw new ArgumentException($"Specified event \"{eventName}\" not defined in type \"{type.Name}\""); | |
} | |
ei.AddEventHandler(value, handler); | |
} | |
private void RemoveEventHandler( | |
object value, | |
string eventName, | |
Delegate handler) | |
{ | |
if (value == null) | |
{ | |
throw new ArgumentNullException("value"); | |
} | |
var type = value.GetType(); | |
var ei = type.GetEvent(eventName); | |
if (ei == null) | |
{ | |
throw new ArgumentException($"Specified event \"{eventName}\" not defined in type \"{type.Name}\""); | |
} | |
ei.RemoveEventHandler(value, handler); | |
} | |
public void Dispose() | |
{ | |
BindingOperations.ClearBinding(this, DependencyPropertyTracker.ValueProperty); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment