MvvmLight学习心得三
MvvmLight的抽象類ViewModelBase繼承了ObservableObject這個類,我們來看看這個類:
/// <summary>/// 一個基類,為了使它的對象屬性必須具有可觀察性/// INotifyPropertyChanged,INotifyPropertyChanging/// </summary>public class ObservableObject:INotifyPropertyChanged,INotifyPropertyChanging可以看見其實它繼承了INotifyPropertyChanged,INotifyPropertyChanging這兩個.net里的接口,在System.dll程序集中:
#region Assembly System.dll, v2.0.50727 // C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll #endregionnamespace System.ComponentModel {// Summary:// Notifies clients that a property value has changed.public interface INotifyPropertyChanged{// Summary:// Occurs when a property value changes.event PropertyChangedEventHandler PropertyChanged;} }當屬性改變時通知客戶端。這個類肯定實現了這兩個接口中的事件,來看下:
/// <summary>/// 如果需要,喚起PropertyChanged事件,非泛型/// </summary>/// <remarks>如果參數名在當前類的屬性中不一致/// 在DEBUG條件下拋出異常VerifyPropertyName中</remarks>/// <param name="propertyName">改變的屬性名稱</param>/// <param name="propertyName"></param>[SuppressMessage("Microsoft.Design","CA1030:UseEventsWhereAppropriate",Justification="This cannot be an event" )]protected virtual void RaisePropertyChanged(string propertyName){VerifyPropertyName(propertyName);var handler = PropertyChanged;if (handler != null){handler(this, new PropertyChangedEventArgs(propertyName));}}還有個就是
protected virtual void RaisePropertyChanging(string propertyName) 參數都是string類型的propertyName.那么更好的肯定是實現這兩個方法的泛型版本:
/// <summary>/// 如果需要,喚起PropertyChanged事件,泛型/// </summary>/// <typeparam name="T"></typeparam>/// <param name="propertyExpression"></param>[SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate",Justification = "This cannot be an event")][SuppressMessage("Microsoft.Design","CA1006:GenericMethodsShouldProvideTypeParameter",Justification = "This syntax is more convenient(方便) than other alternatives(選擇的余地)")]protected virtual void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpression){var handler = PropertyChanged;if (handler != null){var propertyName = GetPropertyName(propertyExpression);handler(this, new PropertyChangedEventArgs(propertyName));}}注意到這里有個GetPropertyName方法:
/// <summary>/// 根據表達式提取(Extract)屬性名字/// </summary>/// <typeparam name="T"></typeparam>/// <param name="propertyExpression"></param>/// <returns></returns>protected string GetPropertyName<T>(Expression<Func<T>> propertyExpression){if (propertyExpression == null){throw new ArgumentNullException("propertyExpression");}//關于Linq的文章,可以參考//http://www.cnblogs.com/lifepoem/archive/2011/12/16/2288017.html//http://www.cnblogs.com/zhili/archive/2012/12/12/LambdaExpression.htmlvar body = propertyExpression.Body as MemberExpression;if (body == null){throw new ArgumentException("Invalid argument", "propertyExpression");}var property = body.Member as PropertyInfo;if (property == null){throw new ArgumentException("Argument is not a property","propertyExpression");}return property.Name;}關于Linq學習的博文,園子里已經有很多人寫過了,可以參考lifepoem和zhili的。
這個類還有兩個重要的泛型方法,Set<T>:
/// <summary>/// 把新值賦給屬性,然后喚起PropertyChanged事件/// </summary>/// <typeparam name="T">屬性類型</typeparam>/// <param name="propertyExpression">確認屬性改變的表達式,翻譯有問題</param>/// <param name="field">保存屬性值的變量</param>/// <param name="newValue">改變過后的新值</param>/// <returns>事件只有在兩個值不相等的情況下才被喚起</returns>protected bool Set<T>(Expression<Func<T>> propertyExpression,ref T field,T newValue){if (EqualityComparer<T>.Default.Equals(field,newValue)){return false;}RaisePropertyChanging(propertyExpression);field = newValue;RaisePropertyChanged(propertyExpression);return true;}另外一個其實也就是把Expression<Func<T>>參數換成string參數而已
protected bool Set<T>(string propertyName,ref T field,T newValue)之前我們的例子中的RaisePropertyChanged就是其實就是調用ViewModelBase里的RaisePropertyChanged函數,因為這個函數是虛函數,所以是調用的ViewModelBase中的RaisePropertyChanged實現:
[SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate",Justification = "This cannot be an event")]protected virtual void RaisePropertyChanged<T>(string propertyName, T oldValue, T newValue, bool broadcast){if (string.IsNullOrEmpty(propertyName)){throw new ArgumentException("This method cannot be called with an empty string", "propertyName");}RaisePropertyChanged(propertyName);if (broadcast){Broadcast(oldValue, newValue, propertyName);}}最后一個參數如果不為true,而且不注冊PropertyChanged事件將不會有任何返回結果。下篇我們介紹NotificationMessage和DialogMessage的簡單使用。
轉載于:https://www.cnblogs.com/johnwonder/archive/2013/01/05/2846749.html
總結
以上是生活随笔為你收集整理的MvvmLight学习心得三的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [转载]ios简单sqlite使用
- 下一篇: Oracle--SQL技巧之二(多行记录