2011-05-13 60 views
2

你好,我有3個關於MVVM模型的問題。MVVM模型應該如何?

  1. 是不是有什麼辦法可以繞過冗餘PropertyChanged("PropName");
  2. 什麼是包裝POCO對象WPF INotifyPropertyChanged, IDataErrorInfo的最佳方式
  3. 我應該怎麼用(WPfWrapers - POCO)交互視圖模型裏面 - 通過鑄造,或財產...

謝謝。

回答

3

這裏有三個答案:

  1. 你找到引發PropertyChanged事件,而沒有經過「PROPNAME」作爲.NET community字符串參數的替代品。但是,它們都有其他缺點(例如性能)。

  2. 的最好方法是直接在模型執行INotifyPropertyChanged和IDataErrorInfo的。這並不總是可能的。如果你需要包裝模型類,那麼你可以看看DataModel的概念。

  3. 我不知道如果我理解過去的問題的權利,但這裏是一個答案。 ViewModel或DataModel應該直接與模型交互。但是這些類不應該直接與View相互作用。使用接口(例如IView)來處理這種情況。

更多信息可以在這裏找到:WPF Application Framework (WAF)

+0

關於第三個問題:[link](http://stackoverflow.com/questions/5990663/abstract-class-cast-operator) – 2011-05-13 20:12:05

1
  1. 是的,你可以用Lamdba表達式來做到這一點。但是,這將花費一些處理器時間(做了一些快速測量:這種方法大約比使用字符串常量慢200倍,請牢記這一點使用上的高度常去波蘇斯表達時):

    private string ExtractPropertyName<T>(Expression<Func<T>> propertyExpresssion) 
    { 
        if (propertyExpresssion == null) 
        { 
         throw new ArgumentNullException("propertyExpresssion"); 
        } 
    
        var memberExpression = propertyExpresssion.Body as MemberExpression; 
        if (memberExpression == null) 
        { 
         throw new ArgumentException("The expression is not a member access expression.", "propertyExpresssion"); 
        } 
    
        var property = memberExpression.Member as PropertyInfo; 
        if (property == null) 
        { 
         throw new ArgumentException("The member access expression does not access a property.", "propertyExpresssion"); 
        } 
    
        if (!property.DeclaringType.IsAssignableFrom(this.GetType())) 
        { 
         throw new ArgumentException("The referenced property belongs to a different type.", "propertyExpresssion"); 
        } 
    
        var getMethod = property.GetGetMethod(true); 
        if (getMethod == null) 
        { 
         // this shouldn't happen - the expression would reject the property before reaching this far 
         throw new ArgumentException("The referenced property does not have a get method.", "propertyExpresssion"); 
        } 
    
        if (getMethod.IsStatic) 
        { 
         throw new ArgumentException("The referenced property is a static property.", "propertyExpresssion"); 
        } 
    
        return memberExpression.Member.Name; 
    } 
    
    private string myProperty; 
    public string MyProperty 
    { 
        get 
        { 
         return myProperty; 
        } 
        set 
        { 
         myProperty = value; 
         this.RaisePropertyChanged(() => MyProperty); 
        } 
    } 
    
    protected void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpression) 
    { 
        var propertyName = ExtractPropertyName(propertyExpression); 
        this.RaisePropertyChanged(propertyName); 
    } 
    
  2. 我認爲你不必包裝它們(除了創建相應的視圖模型)。 POCO用作模型,接口由視圖模型實現。

  3. 當您不包裝POCO時,此問題已過時。
+0

如果POCO將執行它們,它們將取決於WPF。 – 2011-05-13 09:41:51

+0

INotifyPropertyChanged與WPF無關。除此之外,POCO通常用作模型。接口在視圖模型上實現。所以你根本不會模仿這個模型。但我會更新我的第二個答案... – PVitt 2011-05-13 09:44:39

0

也有在你的視圖模型使用的依賴項屬性的選項。許多人似乎並不喜歡這樣做,因爲他們是wpf的一部分並具有線程關聯性(您只能從創建該關鍵對象的線程調用依賴項屬性方法)

我個人從未發現這是一個因爲您查看的問題既取決於wpf,也取決於線程關聯性,所以即使使用INotifyPropertyChanged,您仍然必須從正確的線程中觸發PropertyChanged事件

依賴屬性內置了通知支持,並且不需要wpf做任何反射,所以它們對於數據綁定更快(但是在較小的時間範圍內設置/獲得更慢)

你的場景可能與我的不同,但它有點看我認爲:)

0

您可以使用名爲「CallerMemberName」的.NET 4.5的新功能,以避免硬編碼屬性名稱。