2010-11-27 36 views
2

Je voudrais implémenter l'interface System.ComponentModel.INotifyPropertyChanged pour une propriété sur une classe de base, mais je ne suis pas sûr de savoir comment la connecter.WPF - Implémenter System.ComponentModel.INotifyPropertyChanged pour la classe de base

est ici la signature de la propriété que je voudrais recevoir des notifications pour:

public abstract bool HasChanged(); 

Et mon code dans la classe de base pour la gestion du changement:

public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; 

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

Comment gérer la connexion de l'événement dans la classe de base sans avoir à appeler OnPropertyChanged() dans chaque classe enfant?

Merci,
Sonny

EDIT: OK ... Je pense donc que lorsque la valeur pour hasChanged() change, je suis censé appeler OnPropertyChanged("HasChanged"), mais je ne suis pas sûr de savoir comment obtenir cela dans la classe de base. Des idées?

+0

d'une manière générale, cela est impossible. – Jon

+0

Aussi, 'HasChanged' est une méthode ici, pas une propriété. Copier/coller une erreur? – Jon

+0

pas vrai, il peut toujours mettre à jour la propriété de la classe de base, voir ma réponse édité ci-dessous. – VoodooChild

Répondre

2

Est-ce ce que vous cherchez?

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

} 

Notez que le niveau accessible OnPropertyChanged est protégé. Et puis dans votre classe de béton ou des classes enfants, vous faites:

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: après avoir lu à nouveau la question de l'OP, je me rends compte qu'il ne veut pas appeler la OnPropertyChanged dans la classe des enfants, donc je suis assez sûr cela fonctionne:

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

et en classe des enfants:

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

vous devriez vraiment vérifier l'égalité de valeur et le champ de sauvegarde avant de définir et d'élever l'événement changé if (value! = This.person.name) –

+0

@ Muad'Dib: est-ce parce que le 'this.person' peut être nul? ou Est-ce parce que nous ne voulons pas élever l'événement si rien n'est changé? – VoodooChild

+0

@VoodooChild parce que nous ne voulons pas élever l'événement. Je veux dire, si vous le relevez et rien n'a changé, alors vous êtes, en réalité, en train de mentir. De plus, si vous augmentez inutilement l'événement modifié, vous réduisez les cycles et ralentissez les choses. –