2011-08-08 3 views
2

Je suis nouveau sur MVVM et j'ai un petit problème. J'ai deux commandes d'utilisateur: parent et enfant (avec vue, viewmodel, classes de modèle). Et besoin de passer certaines propriétés de parent à enfant. Pour l'instant ive gérés en écrivant ce code:Passage de la propriété d'une "vue" au viewmodel d'une autre vue dans MVVM

public static readonly DependencyProperty CallbackActionProperty = 
       DependencyProperty.Register("CallbackAction", typeof (Action), 
     typeof (ChildView), new PropertyMetadata(default(Action))); 

public Action CallbackAction 
{ 
    get { return (Action) GetValue(CallbackActionProperty); } 
    set 
    { 
    SetValue(CallbackActionProperty, value); 
    ((ChildViewModel)this.DataContext).CallbackAction = value; // Change ViewModel property too 
    } 
} 

C'est une propriété de dépendance dans ChildView et sur son plateau, j'ai également sa propriété de ViewModel. Après cela, j'accède à cette propriété de dépendance de ParentView et de définir le CallbackAction -> qui définit le CallbackAction dans ViewModel de l'enfant.
code:

this.Loaded += (sender, args) => childUc.CallbackAction = ((ParentViewModel) this.DataContext).RefreshStatuses; 

childUc est usercontrol, situé sur le parent et représenté par ChildView. Le code est moche, donc j'espère voir une meilleure pratique en termes de ne pas casser le modèle. Merci.

+0

Quelle est la question? –

+0

@Mario Vernari, quelle est la bonne façon de faire la chose que j'ai essayé de décrire. – 0x49D1

Répondre

3

Oui, ce code est assez moche. En fait, je me bats pour savoir exactement ce qu'il fait! L'un des principaux locataires du modèle MVVM est que ViewModel doit être testable à l'unité et qu'il devrait être possible de l'exécuter sans la vue. Lorsque vous êtes confronté à ce type de problème, pensez à la vue Modèle seul et ignorez la vue. Votre ParentViewModel a une référence à ChildViewModel, vous pouvez faire une relation bidirectionnelle en ayant ParentViewModel fournir une référence à lui-même lorsque vous créez le ChildViewModel. Cela signifie qu'à partir de ChildViewModel vous pouvez exécuter n'importe quelle méthode publique sur le ParentViewModel.

Dans cet esprit, vous devriez être en mesure de résoudre votre problème!

(En outre, vous ne devez pas ajouter la logique dans votre getter de propriété de dépendance ou poseur, ce code peut ou ne peut pas être appelé en fonction de la façon dont la valeur de votre propriété de dépendance est définie.)

+0

Mmm, belle suggestion! Bien sûr, je peux créer l'interface de Parent et passer une référence de ce type d'interface à Child (je peux avoir beaucoup de contrôleurs parentaux "différents" pour cet enfant). Merci, je vais essayer. La suggestion de penser juste à ViewModel est la meilleure que je pense. Bien sûr, cela doit fonctionner sans View. – 0x49D1

+0

Oui, passer une interface à ChildViewModel qui n'a que les méthodes qu'il devrait être capable d'invoquer est une bonne idée. – ColinE

+1

Les enfants ne devraient jamais savoir qui est leur parent, mais le parent le fait. Si vous voulez "communiquer" quelque chose de n'importe quel descendant, vous devez utiliser une commande.Cela permet d'échanger des données vers l'ascendance sans aucun couplage. –

1

N'écrivez aucune logique dans setter ou getter de DependencyProperty car elle a été appelée par le Framework de différentes manières, pas directement à travers les accesseurs set/get. C'est une règle incontournable.

Aussi chaîne

((ChildViewModel)this.DataContext).CallbackAction = value; 

introduit un couplage entre égalité Vue actuelle et le type ViewModel sous-jacente, ce n'est pas un principe de MVVM.

En cas de dépendance de View, vous devriez envisager de passer des propriétés en utilisant des liaisons en XAML, sinon ParentViewModel aurait dû injecter un modèle ChildViewModel. Donc, ils devraient être conçus pour indiquer que ParentViewModel a un enfant ...

Questions connexes