Skip to content

Instantly share code, notes, and snippets.

@AtsushiSuzuki
Created September 13, 2016 07:35
Show Gist options
  • Save AtsushiSuzuki/2248f366c69709efafc723b9d1c49840 to your computer and use it in GitHub Desktop.
Save AtsushiSuzuki/2248f366c69709efafc723b9d1c49840 to your computer and use it in GitHub Desktop.
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