Lors de la mise en œuvre du ViewModel dans un Modèle-Vue-Vuemodèle architecture de l'application WPF, il semble y avoir deux grands choix sur la façon de faire databindable. J'ai vu les implémentations utiliser DependencyProperty pour les propriétés de la Vue va se lier contre et j'ai vu le ViewModel la mise en œuvre de INotifyPropertyChanged à la place. Ma question est: quand dois-je préférer un plutôt que l'autre? Existe-il des écarts de performances? Est-ce vraiment une bonne idée de donner le ViewModel dépendances à WPF? Que dois-je considérer au moment de prendre la décision de conception?
Réponses
Trop de publicités?Kent a écrit un blog intéressant sur ce sujet: les Modèles de Vue: Poco contre DependencyObjects.
Bref résumé:
- DependencyObjects ne sont pas marqués comme serializable
- Le DependencyObject classe remplacements et les joints de la Equals() et GetHashCode() méthodes
- Un DependencyObject a l'affinité de thread – il ne peut être consulté sur le thread sur lequel il a été créé
Je préfère le POCO approche. Une classe de base pour PresentationModel (aka ViewModel) qui implémente l'interface INotifyPropertyChanged peuvent être trouvés ici: http://compositeextensions.codeplex.com
Le choix est totalement basé sur une logique d'entreprise de l'INTERFACE et de niveau d'abstraction. Si vous ne voulez pas une bonne séparation puis DP va travailler pour vous.
DependencyProperties sera applicable principalement à la VisualElements niveau afin de ne pas être une bonne idée si nous créer beaucoup de DPs pour chacun de nos exigences de l'entreprise. Il y a aussi un coût plus élevé pour les DP que INotifyPropertyChanged. Lors de la conception de WPF/Silverlight essayer de conception de l'INTERFACE utilisateur et le ViewModel totalement distincte de sorte qu'à tout moment on peut changer la Mise en page et des contrôles d'INTERFACE utilisateur (Basé sur le thème et les Styles)
Consultez ce post aussi http://stackoverflow.com/questions/275098/what-applications-could-i-study-to-understand-datamodel-view-viewmodel . Le lien a beaucoup de référence à Modèle-Vue-Vuemodèle modèle, qui est très pertinente pour la présente discussion.
D’un point de vue expressivité, j’ai bien profiter à l’aide de propriétés de dépendance et grincer des dents à la pensée de . En dehors de la
les noms de propriété et de la mémoire possible fuite en raison de l’abonnement aux événements, `` est un mécanisme beaucoup plus explicit.
Propriétés de dépendance impliquent « lorsque ceci, cela » à l’aide de métadonnées statiques facilement compréhensible. C’est une approche déclarative qui obtient mon vote pour l’élégance.
INotifyPropertyChanged
lorsque utilisé vous donne également la possibilité d'ajouter plus de logique dans le code de votre getters et définition de vos propriétés.
DependencyProperty
exemple:
public static DependencyProperty NameProperty = DependencyProperty.Register( "Name", typeof( String), typeof( Customer ) );
public String Name
{
set { SetValue( NameProperty, value ); }
get { return ( String ) GetValue( NameProperty ); }
}
Dans votre getter et setter --- tout ce que vous pouvez faire est de simplement appeler SetValue et GetValue respectivement, b/c dans les autres pièces de la charpente les getter/setter n'est pas appelé, au lieu qu'il appelle directement SetValue, GetValue, de sorte que votre propriété logique wouldnt être exécutée de manière fiable.
Avec INotifyPropertyChanged
, définir un événement:
public event PropertyChangedEventHandler PropertyChanged;
Et puis tout simplement logique de n'importe où dans votre code, puis composez le:
// ...
// Something cool...
// ...
if( this.PropertyChanged != null )
{
PropertyChanged( this, new PropertyChangedEventArgs( "Name" ) );
}
// More cool stuff that will reliably happen...
Cela pourrait être un getter/setter, ou n'importe où ailleurs.