有什麼方法可以避免這種情況。我有很多綁定到DataGridViews的類,它們只是具有默認getter和setter的簡單屬性集合。所以這些類非常簡單。現在我需要爲它們實現INotifyPropertyChanged接口,這會增加代碼量。 有沒有我可以繼承的任何類,以避免編寫所有這些無聊的代碼?我認爲我可以從一些類繼承我的類,並使用一些屬性來修飾屬性,並且它會發揮魔力。那可能嗎?如何避免手動實施INotifyPropertyChanged
我很瞭解面向方面編程,但我寧願做面向對象的方式。
有什麼方法可以避免這種情況。我有很多綁定到DataGridViews的類,它們只是具有默認getter和setter的簡單屬性集合。所以這些類非常簡單。現在我需要爲它們實現INotifyPropertyChanged接口,這會增加代碼量。 有沒有我可以繼承的任何類,以避免編寫所有這些無聊的代碼?我認爲我可以從一些類繼承我的類,並使用一些屬性來修飾屬性,並且它會發揮魔力。那可能嗎?如何避免手動實施INotifyPropertyChanged
我很瞭解面向方面編程,但我寧願做面向對象的方式。
創建一個容器基類,如:
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; } }
}
}
注:非常簡單的代碼
這取決於;你可以使用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;
}
}
使用代碼生成(比如,T4)是另一種方式。請參閱:Automatic INotifyPropertyChanged Implementation through T4 code generation?。
我使用這種方法,它運作良好。
沒有AOP,我不認爲有一個簡單的方法來改造這個到你現有的類。然而,你這樣做,你至少必須改變你的所有屬性。
我使用繼承INotifyPropertyChanged與OnPropertyChanged(字符串propertyName)方法觸發事件的基類。然後,我使用Visual Studio代碼段創建屬性,在屬性設置器中自動調用OnPropertyChanged。
我剛剛找到了ActiveSharp - Automatic INotifyPropertyChanged,我還沒有使用它,但它看起來不錯。
引述它的網站...
發送屬性更改通知 沒有指定屬性名稱爲 字符串。
相反,寫屬性是這樣的:
public int Foo
{
get { return _foo; }
set { SetValue(ref _foo, value); } // <-- no property name here
}
注意,沒有必要列入財產作爲字符串的名稱。 ActiveSharp可靠且正確地爲自己計算出來。它的工作原理基於您的屬性實現通過ref的後臺字段(_foo)。(ActiveSharp使用「通過ref」調用來標識哪個後臺字段已通過,並從該字段標識該屬性)。
這裏是一個類似的解決方案給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();
}
}
也參見http://stackoverflow.com/questions/1315621/implementing-inotifypropertychanged-does-a-better-way-exist – 2011-06-01 11:40:12
HTTP:// code.google.com/p/notifypropertyweaver/也許是有用的 – 2012-02-29 11:38:14