2010-11-27 7 views
2

Ich möchte die System.ComponentModel.INOtifyPropertyChanged-Schnittstelle für eine Eigenschaft auf einer Basisklasse implementieren, aber ich bin mir nicht sicher, wie Sie es anschließen.WPF - Implementieren von System.ComponentModel.INotifyPropertyChanged für Basisklasse

Hier ist die Signatur für die Eigenschaft I-Benachrichtigungen erhalten möchte: mein Code in der Basisklasse

public abstract bool HasChanged(); 

und die Änderung für den Umgang:

public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; 

private void OnPropertyChanged(String info) 
{ 
    PropertyChangedEventHandler handler = PropertyChanged; 
    if (handler != null) 
    { 
     handler(this, new PropertyChangedEventArgs(info)); 
    } 
} 

Wie kann ich den Griff Verbinden des Ereignisses in der Basisklasse, ohne OnPropertyChanged() in jeder Kindklasse aufrufen zu müssen?

Danke,
Sonny

EDIT: OK ... so denke ich, dass, wenn der Wert für Haschanged() ändert sich, ich bin OnPropertyChanged("HasChanged") nennen soll, aber ich bin nicht sicher, wie man das in die Basisklasse. Irgendwelche Ideen?

+0

Generell dies nicht möglich ist. – Jon

+0

Auch "HasChanged" ist hier eine Methode, keine Eigenschaft. Fehler kopieren/einfügen? – Jon

+0

nicht wahr, er kann immer noch die Eigenschaft der Basisklasse aktualisieren, siehe meine bearbeitete Antwort unten. – VoodooChild

Antwort

2

Sind Sie das?

public abstract class ViewModelBase : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    //make it protected, so it is accessible from Child classes 
    protected void OnPropertyChanged(String info) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(info)); 
     } 
    } 

} 

Beachten Sie, dass die Zugriffsstufe OnPropertyChanged geschützt ist. Und dann in der konkreten Klasse oder Kind-Klassen, die Sie tun:

public class PersonViewModel : ViewModelBase 
{ 

    public PersonViewModel(Person person) 
    { 
     this.person = person; 
    } 

    public string Name 
    { 
     get 
     { 
      return this.person.Name; 
     } 
     set 
     { 
      this.person.Name = value; 
      OnPropertyChanged("Name"); 
     } 
    } 
} 

EDIT: nach wieder die OP Frage zu lesen, ich merke, dass er nicht die OnPropertyChanged in der Kinderklasse aufrufen will, also bin ich ziemlich sicher, dies funktioniert:

public abstract class ViewModelBase : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    private bool hasChanged = false; 
    public bool HasChanged 
    { 
     get 
     { 
      return this.hasChanged; 
     } 
     set 
     { 
      this.hasChanged = value; 
      OnPropertyChanged("HasChanged"); 
     } 
    } 

    //make it protected, so it is accessible from Child classes 
    protected void OnPropertyChanged(String info) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(info)); 
     } 
    } 
} 

und in der Kinderklasse:

public class PersonViewModel : ViewModelBase 
{ 
    public PersonViewModel() 
    { 
     base.HasChanged = true; 
    } 
} 
+0

Sie sollten wirklich auf Gleichheit von Wert und Unterstützungsfeld überprüfen, bevor Sie das geänderte Ereignis setzen und erhöhen if (Wert! = This.person.name) –

+0

@ Muad'Dib: liegt das daran, dass 'this.person' null sein kann? Oder ist es, weil wir das Ereignis nicht erhöhen möchten, wenn sich nichts ändert? – VoodooChild

+0

@VoodooChild, weil wir das Ereignis nicht erhöhen möchten. Ich meine, wenn du es erhöhst und nichts geändert hat, dann lügst du im Wesentlichen. Wenn Sie das geänderte Ereignis unnötigerweise aufheben, tendieren Sie auch dazu, Zyklen zu verlangsamen und die Dinge zu verlangsamen. –

Verwandte Themen