當我們用MVVM的時候要實現INotifyPropertyChanged,每次都要實現這個接口比較麻煩,所以基類的作用就體現出來了。代碼如下:
public class ViewModelBase : INotifyPropertyChanged, IDisposable { public event PropertyChangedEventHandler PropertyChanged; public bool IsInDesignMode; /// <summary> 顯示名稱 </summary> public virtual string DisplayName { get; protected set; } #region 構造 public ViewModelBase() { } #endregion private void OnPropertyChanged(string propertyName) { if (this.PropertyChanged != null) { this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } private static string GetProperyName(string methodName) { if (methodName.StartsWith("get_") || methodName.StartsWith("set_") || methodName.StartsWith("put_")) { return methodName.Substring(4); } throw new Exception(methodName + " not a method of Property"); } protected void SetProperty<T>(ref T name, T value) { if (object.Equals(name, value)) return; name = value; string propertyName = GetProperyName(new System.Diagnostics.StackTrace(true).GetFrame(1).GetMethod().Name); this.OnPropertyChanged(propertyName); } #region IDisposable Members public void Dispose() { this.OnDispose(); } /// <summary> /// 若支持IDisposable,請重寫此方法,當被調用Dispose時會執行此方法。 /// </summary> protected virtual void OnDispose() { } #endregion } public class CommandBase : System.Windows.Input.ICommand { private Action<Object> _doWork; private readonly Func<object, bool> _canExecute; /// <summary> /// 實例化一個CommandBase對象 /// </summary> /// <param name="doWork">委托一個有object類型參數的命令執行函數</param> /// <param name="canExecute">委托一個有object類型參數的命令是否能被執行的函數(可選)</param> /// <exception cref="ArgumentNullException">參數command不可以為null引用</exception> public CommandBase(Action<object> doWork, Func<object, bool> canExecute = null) { if (doWork == null) throw new ArgumentNullException("doWork"); _canExecute = canExecute; _doWork = doWork; } public bool CanExecute(Object parameter) { return true; } public void Execute(Object parameter) { if (this._doWork != null) this._doWork(parameter); } public event EventHandler CanExecuteChanged { add { } remove { } } }
使用方式如下,例:
public class TestViewModel : ViewModelBase { public TestViewModel() { this.LoadCommand = new CommandBase((Object parameter) => Loading()); } #region 屬性 private string _name; /// <summary> 是否可用 </summary> public string IsEnable { get { return _name; } set { base.SetProperty<string>(ref this._name, value); } } #endregion #region 命令 /// <summary> /// 窗口加載命令 /// </summary> public ICommand LoadCommand { get; set; } #endregion #region 方法 /// <summary> /// 初始化方法 /// </summary> public void Loading() { } #endregion }
看了例子后,是不是感覺很簡單呢?詳細的測試代碼會再后續的文章中提供給大家參考。