diff -r 09d0bc6970b5 -r 1ec0ef228158 src/FingersDance.ViewModel/ViewModelBase.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/FingersDance.ViewModel/ViewModelBase.cs Tue Sep 15 13:30:58 2009 +0200 @@ -0,0 +1,127 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.ComponentModel; +using System.Diagnostics; + +namespace FingersDance.ViewModel +{ + /// + /// Base class for all ViewModel classes in the application. + /// It provides support for property change notifications + /// and has a DisplayName property. This class is abstract. + /// + public abstract class ViewModelBase : INotifyPropertyChanged, IDisposable + { + #region Constructor + + protected ViewModelBase() + { + } + + #endregion // Constructor + + #region DisplayName + + /// + /// Returns the user-friendly name of this object. + /// Child classes can set this property to a new value, + /// or override it to determine the value on-demand. + /// + public virtual string DisplayName { get; protected set; } + + #endregion // DisplayName + + #region Debugging Aides + + /// + /// Warns the developer if this object does not have + /// a public property with the specified name. This + /// method does not exist in a Release build. + /// + [Conditional("DEBUG")] + [DebuggerStepThrough] + public void VerifyPropertyName(string propertyName) + { + // Verify that the property name matches a real, + // public, instance property on this object. + if (TypeDescriptor.GetProperties(this)[propertyName] == null) + { + string msg = "Invalid property name: " + propertyName; + + if (this.ThrowOnInvalidPropertyName) + throw new Exception(msg); + else + Debug.Fail(msg); + } + } + + /// + /// Returns whether an exception is thrown, or if a Debug.Fail() is used + /// when an invalid property name is passed to the VerifyPropertyName method. + /// The default value is false, but subclasses used by unit tests might + /// override this property's getter to return true. + /// + protected virtual bool ThrowOnInvalidPropertyName { get; private set; } + + #endregion // Debugging Aides + + #region INotifyPropertyChanged Members + + /// + /// Raised when a property on this object has a new value. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Raises this object's PropertyChanged event. + /// + /// The property that has a new value. + protected virtual void OnPropertyChanged(string propertyName) + { + this.VerifyPropertyName(propertyName); + + PropertyChangedEventHandler handler = this.PropertyChanged; + if (handler != null) + { + var e = new PropertyChangedEventArgs(propertyName); + handler(this, e); + } + } + + #endregion // INotifyPropertyChanged Members + + #region IDisposable Members + + /// + /// Invoked when this object is being removed from the application + /// and will be subject to garbage collection. + /// + public void Dispose() + { + this.OnDispose(); + } + + /// + /// Child classes can override this method to perform + /// clean-up logic, such as removing event handlers. + /// + protected virtual void OnDispose() + { + } + +#if DEBUG + /// + /// Useful for ensuring that ViewModel objects are properly garbage collected. + /// + ~ViewModelBase() + { + string msg = string.Format("{0} ({1}) ({2}) Finalized", this.GetType().Name, this.DisplayName, this.GetHashCode()); + System.Diagnostics.Debug.WriteLine(msg); + } +#endif + + #endregion // IDisposable Member + } +}