Mercurial > silverbladetech
diff MetroWpf/MetroWpf.Xaml/Events/WeakPropertyChangeNotifier.cs @ 17:7721a1270363
New files added during dev
author | stevenh7776 stevenhollidge@hotmail.com |
---|---|
date | Wed, 14 Mar 2012 01:23:57 +0700 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MetroWpf/MetroWpf.Xaml/Events/WeakPropertyChangeNotifier.cs Wed Mar 14 01:23:57 2012 +0700 @@ -0,0 +1,111 @@ +using System; +using System.ComponentModel; +using System.Windows; +using System.Windows.Data; + +namespace MetroWpf.Xaml.Events +{ + /// <summary> + /// http://agsmith.wordpress.com/2008/04/07/propertydescriptor-addvaluechanged-alternative/ + /// </summary> + public sealed class WeakPropertyChangeNotifier + : DependencyObject, IDisposable + { + #region Member Variables + private readonly WeakReference _propertySource; + #endregion // Member Variables + + #region Constructor + public WeakPropertyChangeNotifier(DependencyObject propertySource, string path) + : this(propertySource, new PropertyPath(path)) + { + } + public WeakPropertyChangeNotifier(DependencyObject propertySource, DependencyProperty property) + : this(propertySource, new PropertyPath(property)) + { + } + public WeakPropertyChangeNotifier(DependencyObject propertySource, PropertyPath property) + { + if (null == propertySource) + throw new ArgumentNullException("propertySource"); + if (null == property) + throw new ArgumentNullException("property"); + + this._propertySource = new WeakReference(propertySource); + + var binding = new System.Windows.Data.Binding(); + binding.Path = property; + binding.Mode = BindingMode.OneWay; + binding.Source = propertySource; + BindingOperations.SetBinding(this, ValueProperty, binding); + } + #endregion // Constructor + + #region PropertySource + public DependencyObject PropertySource + { + get + { + try + { + // note, it is possible that accessing the target property + // will result in an exception so i’ve wrapped this check + // in a try catch + return this._propertySource.IsAlive + ? this._propertySource.Target as DependencyObject + : null; + } + catch + { + return null; + } + } + } + #endregion // PropertySource + + #region Value + /// <summary> + /// Identifies the <see cref="Value"/> dependency property + /// </summary> + public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", + typeof(object), typeof(WeakPropertyChangeNotifier), new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnPropertyChanged))); + + private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + WeakPropertyChangeNotifier notifier = (WeakPropertyChangeNotifier)d; + if (null != notifier.ValueChanged) + notifier.ValueChanged(notifier, EventArgs.Empty); + } + + /// <summary> + /// Returns/sets the value of the property + /// </summary> + /// <seealso cref="ValueProperty"/> + [Description("Returns/sets the value of the property")] + [Category("Behavior")] + [Bindable(true)] + public object Value + { + get + { + return (object)this.GetValue(ValueProperty); + } + set + { + this.SetValue(ValueProperty, value); + } + } + #endregion //Value + + #region Events + public event EventHandler ValueChanged; + #endregion // Events + + #region IDisposable Members + public void Dispose() + { + BindingOperations.ClearBinding(this, ValueProperty); + } + #endregion + } +}