2010-06-28 108 views
8

有什麼方法可以避免這種情況。我有很多綁定到DataGridViews的類,它們只是具有默認getter和setter的簡單屬性集合。所以這些類非常簡單。現在我需要爲它們實現INotifyPropertyChanged接口,這會增加代碼量。 有沒有我可以繼承的任何類,以避免編寫所有這些無聊的代碼?我認爲我可以從一些類繼承我的類,並使用一些屬性來修飾屬性,並且它會發揮魔力。那可能嗎?如何避免手動實施INotifyPropertyChanged

我很瞭解面向方面編程,但我寧願做面向對象的方式。

+1

也參見http://stackoverflow.com/questions/1315621/implementing-inotifypropertychanged-does-a-better-way-exist – 2011-06-01 11:40:12

+0

HTTP:// code.google.com/p/notifypropertyweaver/也許是有用的 – 2012-02-29 11:38:14

回答

4

創建一個容器基類,如:

abstract class Container : INotifyPropertyChanged 
{ 
    Dictionary<string, object> values; 

    protected object this[string name] 
    { 
    get {return values[name]; } 
    set 
    { 
     values[name] = value; 
     PropertyChanged(this, new PropertyChangedEventArgs(name)); 
    } 
    } 
} 

class Foo : Container 
{ 
    public int Bar 
    { 
    {get {return (int) this["Bar"]; }} 
    {set { this["Bar"] = value; } } 
    } 
} 

注:非常簡單的代碼

0

如果您適合AOP,可以嘗試使用PostSharp。搜索PostSharp INotifyPropertyChanged,你會發現很多文章解釋它,如thisthis

9

這取決於;你可以使用PostSharp來編寫這個屬性,編織者;不過,我會被誘惑,只是做手工 - 也許使用一個通用的方法來處理數據的更新,即

private string name; 
public string Name { 
    get { return name; } 
    set { Notify.SetField(ref name, value, PropertyChanged, this, "Name"); } 
} 

有:

public static class Notify { 
    public static bool SetField<T>(ref T field, T value, 
     PropertyChangedEventHandler handler, object sender, string propertyName) 
    { 
     if(!EqualityComparer<T>.Default.Equals(field,value)) { 
      field = value; 
      if(handler!=null) { 
       handler(sender, new PropertyChangedEventArgs(propertyName)); 
      } 
      return true; 
     } 
     return false; 
    } 
} 
1

沒有AOP,我不認爲有一個簡單的方法來改造這個到你現有的類。然而,你這樣做,你至少必須改變你的所有屬性。

我使用繼承INotifyPropertyChanged與OnPropertyChanged(字符串propertyName)方法觸發事件的基類。然後,我使用Visual Studio代碼段創建屬性,在屬性設置器中自動調用OnPropertyChanged。

0

我剛剛找到了ActiveSharp - Automatic INotifyPropertyChanged,我還沒有使用它,但它看起來不錯。

引述它的網站...


發送屬性更改通知 沒有指定屬性名稱爲 字符串。

相反,寫屬性是這樣的:

public int Foo 
{ 
    get { return _foo; } 
    set { SetValue(ref _foo, value); } // <-- no property name here 
} 

注意,沒有必要列入財產作爲字符串的名稱。 ActiveSharp可靠且正確地爲自己計算出來。它的工作原理基於您的屬性實現通過ref的後臺字段(_foo)。(ActiveSharp使用「通過ref」調用來標識哪個後臺字段已通過,並從該字段標識該屬性)。

1

這裏是一個類似的解決方案給Marc,已經被擴展,以允許多個屬性onpropertychanges和多個RaiseCanExecuteChanged

最簡單的例子使用

string _firstName; 
public string FirstName 
{ 
    get { return _firstName; } 
    set { OnPropertyChanged(ref _firstName, value, "FirstName"); } 
} 
使用多個屬性的更新和多條命令

先進例子

string _firstName; 
public string FirstName 
{ 
    get { return _firstName; } 
    set { OnPropertyChanged(ref _firstName, value, "FirstName", "FullName", Command1, Command2); } 
} 

先進的示例調用OnProperty更改名字和全名,也調用RaiseCanExecut eChanged爲Command和Command

基視圖模型代碼

protected void OnPropertyChanged<T>(ref T field, T value, params object[] updateThese) 
{ 
    if (!EqualityComparer<T>.Default.Equals(field, value)) 
    { 
     field = value; 
     OnPropertyChanged(updateThese); 
    } 
} 

protected void OnPropertyChanged(params object[] updateThese) 
{ 
    if (PropertyChanged != null) 
    { 
     foreach (string property in updateThese.Where(property => property is string)) 
      PropertyChanged(this, new PropertyChangedEventArgs(property)); 

     foreach (DelegateCommand<object> command in updateThese.Where(property => property is DelegateCommand<object>)) 
      command.RaiseCanExecuteChanged(); 
    } 
}