2010-12-01 54 views
3

我開發了很多視圖模型,它們是:什麼樣的編譯器魔術我們需要更多?

1)所有必須實現INotifyPropertyChanged可綁定到UI。

2)屬性設置者必須在更改時提高PropertyChanged。

3)PropertyChanged事件必須提供正確的屬性名稱。

如果你(像我一樣)並列寫像這樣的:


public string Name 
{ 
    get 
    { 
    return _name; 
    } 
    set 
    { 
    if (_name != value) 
    { 
     _name = value; 
     RaisePropertyChanged("Name"); 
    } 
    } 
} 

然後重構這個方法是這樣,有時忘了更新的屬性名稱直譯:


string _fundName; 
public string FundName 
{ 
    get 
    { 
    return _fundName; 
    } 
    set 
    { 
    if (_fundName != value) 
    { 
     _fundName = value; 
     RaisePropertyChanged("Name"); 
    } 
    } 
} 

,然後花一一天來調試爲什麼你的用戶界面不刷新和數據綁定無法正常工作。

然後,我們需要的是某種魔法。

如果我只需要這樣寫:


[Magic] // implicit transformation 
public string FundName { get; set; } 

,或者如果我有很多的特性:


[Magic] 
public class MyViewModel 
{ 
    public string FundName { get; set; } 
    public string FundType { get; set; } 

    [NoMagic] // suppress transformation 
    public int InternalId { get; set; } 
} 

所以我剛纔已經開發出MSBuild任務生成後,要做到這一點魔術( http://kindofmagic.codeplex.com)。

問題是,你會更喜歡什麼樣的魔法後處理?

自動執行INotifyPropertyChanging是否有意義?

+0

如何爲INotifyPropertyChanging創建相同的事情? – 2010-12-01 17:57:34

+0

@CommanderZ你是否實現並使用INotifyPropertyChanging?如果是這樣的話?也許你想評論http://stackoverflow.com/questions/3835788/other-than-linq-to-sql-does-anything-else-consume-inotifypropertychanging – Simon 2010-12-01 23:02:55

回答

1

如果我們要生成漂亮的代碼,我想我會更喜歡一種更容易生成DependancyProperties的方法。我使用的snippit無疑是有幫助的,但我不是一個粉絲,當你改變和強制回調以及元數據選項時,代碼看上去很混亂。也許我會在下班後嘗試模擬一個樣本。

編輯:嗯,這裏有一個概念。如果將匿名方法傳遞給屬性,它看起來會更聰明,但它仍然是一個提升。

前:

[DpDefault("The Void")] 
[DpCoerce(new CoerceValueCallback(MainWindow.CoerceAddress))] 
[DpChanged(new PropertyChangedCallback(MainWindow.ChangeAddress1))] 
[DpChanged(new PropertyChangedCallback(MainWindow.ChangeAddress2))] 
[DpOptions(FrameworkPropertyMetadataOptions.Inherits)] 
public string Address { 
    get { return Dp.Get<string>(); } 
    set { 
     if (Dp.Get<string>() != value) { 
      Dp.Set(value); 
      PostOffice.SendMailToTheBoss("I moved!"); 
     } 
    } 
} 

後:

public string Address { 
    get { return (string)GetValue(AddressProperty); } 
    set { 
     if ((string)GetValue(AddressProperty) != value) { 
      SetValue(AddressProperty, value); 
      PostOffice.SendMailToTheBoss("I moved!"); 
     } 
    } 
} 

public static readonly DependencyProperty AddressProperty = 
    DependencyProperty.Register("Address", typeof(string), typeof(MainWindow), 
     new FrameworkPropertyMetadata((string)"The Void", 
      FrameworkPropertyMetadataOptions.Inherits, 
      new PropertyChangedCallback(MainWindow.ChangeAddress1) 
       + new PropertyChangedCallback(MainWindow.ChangeAddress2), 
      new CoerceValueCallback(MainWindow.CoerceAddress))); 

通常情況下,只有 'DpDefault' 屬性將被使用,但即使它不會使代碼更短,它肯定使它清晰。這裏將是一個較爲典型的例子:

前:

[DpDefault("The Void")] 
public string Address { get; set; } 

後:

public string Address { 
    get { return (string)GetValue(AddressProperty); } 
    set { SetValue(AddressProperty, value); } 
} 

public static readonly DependencyProperty AddressProperty = 
    DependencyProperty.Register("Address", typeof(string), typeof(MainWindow), 
     new UIPropertyMetadata((string)"The Void")); 
0

有些事情可能會讓你的生活變得更容易一些......(我從Caliburn Micro那裏找到了它)。

public virtual void NotifyOfPropertyChange<TProperty>(Expression<Func<TProperty>> property) { 
      NotifyOfPropertyChange(property.GetMemberInfo().Name); 
     } 

這樣就可以執行以下操作..

NotifyOfProperyChange(()=> this.PropertyName);

這會在設計時突出顯示代碼的任何問題,而不是運行時。

Caliburn Micro是一個非常棒的小框架,您應該看一看,它消除了MVVM和Silverlight/WPF所涉及的大量佈線問題!

+0

我一直在使用C.M以及。但坦率地說,這只是爲了得到一個正確的屬性名稱而浪費了很多CPU週期。 KindOfMagic項目背後的主要原因是儘可能保持性能,儘可能爲用戶輸入零。 – 2010-12-01 17:26:24

1

「魔術」幾乎總是方法或屬性或任何語言變量的可怕名稱。您應該將該屬性重命名爲更具描述性的內容。想象一下,你只是一個隨機的互聯網行人,偶然發現一個屬性爲「Magic」的代碼,它告訴你關於代碼的是什麼?完全沒有:)

無論如何,我會嘗試你的代碼,它有潛力是一個比較節省。這絕對應該是.NET的一部分。

+0

屬性名稱魔術,肯定會吸引我的注意力。但是,我同意你的看法。尋找更好的名字,任何想法? – 2010-12-01 17:41:04

+0

我認爲NotifyPropertyChanged會工作得很好。 – 2010-12-01 17:56:48

+0

這不是一個真正的答案。 – Simon 2010-12-01 23:03:43

4

試試這個

http://code.google.com/p/notifypropertyweaver/

  • 沒有屬性需要
  • 次​​
  • 沒有提及需要
  • 沒有基類需要

這是我關於它的博客文章

http://codesimonsays.blogspot.com/2010/11/attempting-to-solve-inotifypropertychan.html

它支持您請求

  • NotifyPropertyAttribute屬性(通知物業)
  • NotifyForAllAttribute(通知用於對類型的所有屬性)
  • NotifyIgnoreAttribute(不通知一個屬性或類型)
  • AlsoNotifyFor(允許通知指向一個不同屬性碼的注射)

雖然這些都是可選的,並且設計用於微調。通過分析現有的IL,大多數注射是按照慣例完成的。

相關問題