2010-06-28 4 views
8

Gibt es eine Möglichkeit, dies zu vermeiden. Ich habe viele Klassen, die an DataGridViews gebunden sind und sie sind nur eine einfache Sammlung von Eigenschaften mit Standard-Getter und Setter. Also diese Klassen sind sehr einfach. Jetzt muss ich die INotifyPropertyChanged-Schnittstelle für sie implementieren, die die Menge an Code sehr erhöhen wird. Gibt es irgendeine Klasse, die ich erben kann, um zu vermeiden, all diesen langweiligen Code zu schreiben? Ich stelle mir vor, dass ich meine Klassen von einer Klasse erben kann und die Eigenschaften mit einigen Attributen dekoriere und es die Magie macht. Ist das möglich?Wie vermeidet man die manuelle Implementierung von INotifyPropertyChanged

Ich bin mir der aspektorientierten Programmierung bewusst, aber ich würde es lieber objektorientiert machen.

+1

siehe auch http://stackoverflow.com/questions/1315621/implementing-inotifypropertychanged-does-a-better-way-exist –

+0

http: // code.google.com/p/notifypropertyweaver/ möglicherweise nützlich –

Antwort

4

Erstellen eines Containers Basisklasse, zB:

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; } } 
    } 
} 

Hinweis: sehr vereinfachten Code

0

Wenn Sie AOP zugänglich sind, können Sie versuchen, PostSharp zu verwenden. Suchen Sie nach PostSharp INotifyPropertyChanged und Sie werden viele Artikel finden, die es erklären, wie this und this.

9

Es hängt davon ab; Sie könnten PostSharp verwenden, um ein solches Attribut zu schreiben, das vom Weber geschrieben wird; jedoch würde ich es versucht sein, nur manuell tun - vielleicht ein gemeinsames Verfahren unter Verwendung der Daten-Updates für die Handhabung, dh

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

mit:

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

Ohne AOP, ich glaube nicht, dass es eine einfache Möglichkeit gibt, dies zu Ihren bestehenden Klassen nachzurüsten. Wie auch immer Sie es tun, Sie werden mindestens alle Ihre Eigenschaften ändern müssen.

Ich verwende eine Basisklasse, die INotifyPropertyChanged mit einer OnPropertyChanged (string propertyName) -Methode erbt, um das Ereignis auszulösen. Ich verwende dann ein Visual Studio Code-Snippet, um Eigenschaften zu erstellen, die OnPropertyChanged im Eigenschaftensetter automatisch aufrufen.

0

Ich habe gerade ActiveSharp - Automatic INotifyPropertyChanged gefunden, ich habe es noch zu benutzen, aber es sieht gut aus.

Zitat aus es Website ist ...


senden Eigenschaft Änderungsbenachrichtigungen ohne Angabe Eigenschaftsnamen als String.

Stattdessen schreiben Eigenschaften wie folgt aus:

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

Hinweis, dass es keine Notwendigkeit gibt, den Namen der Eigenschaft als String enthalten. ActiveSharp erfasst das zuverlässig und richtig. Es funktioniert basierend auf der Tatsache, dass Ihre Property-Implementierung das Backing-Feld (_foo) durch Ref übergeben.(ActiveSharp verwendet diesen "by ref" -Aufruf, um zu identifizieren, welches Hintergrundfeld übergeben wurde, und aus dem Feld identifiziert es die Eigenschaft).

1

Hier ist eine ähnliche Lösung zu Marc, die mehrere Eigenschaft onpropertychanges zu ermöglichen, wurde erweitert und mehrere RaiseCanExecuteChanged

einfachste Beispiel für die Verwendung

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

erweiterte Beispiel mehrere Eigenschaft Updates und mehrere Befehle

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

Das erweiterte Beispiel ruft OnProperty auf Vorname und Vollname geändert auf und ruft RaiseCanExecut auf eChanged für command1 und command2

Basis Ansichtsmodell Code

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(); 
    } 
} 
Verwandte Themen