2012-11-06 2 views
5

Question sur le modèle MVVM où je pense que j'ai tort.Passage de l'objet à viewmodel

Lorsqu'un événement se produit touché dans une vue que je veux un message au popup i.e. .:

private void marker_TouchDown(MessageObject msgData) 
{ 
    CustomMessageControl message = new CustomMessageControl() {Width = 610, Height = 332}; 
    CustomMessageViewModel messageVM = new CustomMessageViewModel(msgData); 
    message.DataContext = messageVM; 
    //Add to canvas 
} 

Mon viewmodel:

public class CustomMessageViewModel 
{ 
    public MessageObject message { get; set; } 

    public CustomMessageViewModel(MessageObject message) 
    { 
     this.MessageObject = message; 
    } 
} 

Cela fonctionne, mais ne se sent pas bien. Est-ce une manière acceptable de remplir le modèle de vue?

+0

Généralement viewmodels utilisera l'interface INPC (http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx) pour prendre en charge notifier la vue/consommateur que les propriétés ont été mises à jour. Je déconseille fortement de redéfinir le datacontext dans le code à un nouveau viewmodel lorsqu'il est joint dans ce scénario. –

+0

Merci Quinton, je comprends l'utilisation de l'INPC. Je regarde peut-être cela de manière trop littérale mais ici quelqu'un clique sur une vue et je veux lancer une nouvelle vue en passant des données relatives au point sur lequel elles ont cliqué. –

+1

Excusez mon écrémage sur le code, vous faites en effet ce qui est généralement considéré comme correct, il peut ne pas être si joli dans le code mais est la façon standard d'instancier et de transmettre des données à un viewmodel, il y a plusieurs frameworks MVVM dans leur conception qui pourrait vous intéresser mais si vous voulez tout gérer manuellement, c'est généralement l'approche acceptée. –

Répondre

2

Je crois que vous violez MVVM dans la création du contrôle dans le modèle de vue. Ceci n'est pas testable, votre modèle de vue a pour créer le contrôle maintenant et cela ne devrait pas être une exigence pour le test (cela souligne l'absence de séparation des préoccupations entre l'interface utilisateur et le modèle de vue). Au lieu de créer le contrôle, il est tout à fait acceptable que votre modèle de vue déclenche un événement de sa propre initiative. Dans ce cas, vous souhaitez passer le modèle de vue que vous voulez la boîte de dialogue/superposition/contrôle pour se lier à quelque chose comme ceci:

public class CustomMessageControlEventArgs : EventArgs 
{ 
    public CustomMessageViewModel CustomMessageViewModel { get; set; } 
} 

public event EventHandler<CustomMessageControlEventArgs> 
    ShowCustomMessageControl; 

private void marker_TouchDown(MessageObject msgData) 
{ 
    // Create the view model. 
    var message = ...; 

    // Get the events. 
    var events = ShowCustomMessageControl; 

    // Fire. 
    if (events != null) events(this, 
     new CustomMessageControlEventArgs { 
      MessageObject = new CustomMessageViewModel(msgData) 
     }); 
} 

Ensuite, dans votre code d'interface utilisateur, vous lier à l'événement, puis affiche l'interface utilisateur appropriée pour cet événement. Rappelez-vous, MVVM ne se limite pas à pouvoir déclarer tout en XAML ou lier des données à l'interface utilisateur via juste des liaisons de données, il s'agit de séparer correctement le code.

Vous voulez séparer le ce que de ce qui est affiché (le modèle de vue) de la façon dont de ce qui est affiché (l'interface utilisateur); en tirant un événement, vous maintenez cette séparation des préoccupations.

Oui, vous devrez écrire du code (ou vous pourriez le faire en modifiant la notification de la propriété, mais c'est plus laid, franchement), mais il maintient la séparation et permet une facilité de testabilité sans avoir à faire appel à un utilisateur éléments d'interface.

Questions connexes