2009-08-28 10 views
4

Existe-t-il une manière concise de définir des propriétés dans un ViewModel pour la liaison de données dans C# WPF? La définition de la propriété suivante est très bavard, surtout quand il y a beaucoup de propriétés:Une manière concise de définir des propriétés pour la liaison de données MVVM dans C# WPF

private bool mSomeProperty; 

public bool SomeProperty 
{ 
    get { return this.mSomeProperty; } 
    set 
    { 
     if (value != this.mSomeProperty) 
     { 
      this.mSomeProperty = value; 
      OnPropertyChanged(new PropertyChangedEventArgs("SomeProperty")); 
     } 
    } 
} 

Répondre

3

en C#, je tiens à faire une classe de base et de mettre certaines méthodes d'aide à ce sujet. Ensuite, je fais en sorte que mes ViewModels en descendent. Ceci est de la mémoire, mais il est quelque chose comme ceci:

public class Observable : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    protected void SetProperty<T>(ref T backingField, T newValue, 
     string propertyName) 
    { 
     if (Equals(backingField, newValue)) 
      return; 
     backingField = newValue; 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, 
       new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

Et, dans l'usage:

public class MyClass : Observable 
{ 
    private bool m_someProperty; 

    public bool SomeProperty 
    { 
     get { return m_someProperty; } 
     set { SetProperty(ref m_someProperty, value, "SomeProperty"); } 
    } 
} 
+0

Ceci est en fait identique à une solution que je l'ai déjà mis en œuvre, mais il se sent encore maladroit pour moi. Cependant, c'est un pas dans la bonne direction. –

+0

@emddudley - En fait, sa méthode d'implémentation de INotifyPropertyChanged dans la classe de base est une amélioration très importante par rapport au code de votre question. Si vous utilisez votre code et essayez de créer une classe dérivée, vous ne pouvez pas déclencher l'événement de la classe de base à partir de la classe dérivée. Vous devez pratiquement créer une méthode NotifyPropertyChanged() dans votre classe de base pour que cela fonctionne. –

0

Si vous utilisez le langage Delphi Prism (langage .NET base Pascal), vous ajoutez simplement le mot-clé notify, et compilateur implémente automatiquement INotifyPropertyChanged et écrit tout le code passe-partout pour vous:

property SomeProperty: bool; notify; 
0

Je pense que vous ne serez pas obtenir la déclaration de propriété beaucoup plus petite que cela, du moins pas avec des moyens « normaux ». Vous pouvez utiliser un intercepteur de château pour prendre soin de l'événement raisal.

public class MyViewModel : INotifyPropertyChanged 
{ 
    public event PropertyChanged; 
    public void FirePropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) PropertyChanged(propertyName); 
    } 

    public virtual string MyProperty { get; set; } 
    public virtual string MyProperty2 { get; set; } 
} 

L'intercepteur devrait déclencher l'événement a changé la propriété:

public class PropertyChangedInterceptor : IInterceptor 
{ 
    public void Intercept(IInvocation invocation) 
    { 
     //Pseudo code 
     if (invocation.Method is Property Setter) 
     { 
      Call FirePropertyChanged of invocation.InvocationTarget ; 
     } 
    } 
} 

Vous devez juste vous assurer que les propriétés du modèle de votre vue sont le modèle virtuel et votre point de vue est toujours un proxy et non le point de vue modèle lui-même.

Cordialement

1

Vous pouvez toujours utiliser DependencyProperties et propdp votre coeur ...

+2

Je n'utiliserai pas DependencyProperties dans un ViewModel. Voir http://stackoverflow.com/questions/291518/inotifypropertychanged-vs-dependencyproperty-in-viewmodel pour plus d'informations. – jbe

+0

C'est vraiment à vous. Le message que vous avez lié à ne donne pas de bonnes raisons de ne pas utiliser DP autres que ceux qui sont plus lourds que les POCO. À moins que vous ne rencontriez des problèmes pour les utiliser, l'optimisation prématurée de l'équation est ... une optimisation prématurée. Un projet sur lequel je travaille en ce moment a ~ 40 VM et M, qui étendent DP, et je n'ai pas remarqué que l'application tourne lentement. – Will

0

Vous pouvez envisager PostSharp qui vous permettra de décorer la propriété (que vous pourriez ensuite redéfinir comme propriété auto) et d'injecter dans le setter la ligne qui déclenche l'événement NotifyPropertyChanged. Un avantage supplémentaire est que vous vous débarrasser de la chaîne qui est le même que le nom de la propriété.

Ce n'est pas idéal parce que vous avez besoin de cet outil et il ne sera pas immédiatement évident si vous regardez le code plus tard, mais il le rend nettement plus net.

J'espérais que MSFT ajouterait un tel attribut au C# 4 mais je suppose que nous devrons attendre le C# 5, voire pas du tout.

Questions connexes