2009-06-11 10 views
5

Je peux voir deux façons de raccorder ViewModel à la vue. L'un est en XAML et l'autre à travers l'injection de dépendance dans le code derrière.Accrochage du ViewModel à la vue dans Silverlight

Quelle méthode est la plus préférable? Je préfère la méthode xaml parce que je ne veux pas du tout de code dans le code, mais y a-t-il des problèmes avec l'un sur l'autre?

<navigation:Page x:Class="MyNamespace.MyViewModel" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:ViewModel="clr-namespace:MyNameSpace.MyViewModel" 
    xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation" 
    Title="ViewModel Page" > 

    <navigation:Page.Resources> 
     <ViewModel:MyViewModel x:Key="ViewModel"></ViewModel:MyViewModel> 
    </navigation:Page.Resources> 

    <Grid x:Name="LayoutRoot" Background="White" 
      DataContext="{StaticResource ViewModel}"> 

    </Grid> 
</navigation:Page> 

OU

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Net; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Animation; 
using System.Windows.Shapes; 
using System.Windows.Navigation; 

namespace MyNamespace 
{ 
    public partial class MyView : Page 
    { 
     public MyView() 
     { 
      InitializeComponent(MyViewModel viewModel); 

      this.DataContext = viewModel; 
     } 
    } 
} 

Répondre

3

Shawn a un bon post sur View or ViewModel premier. Avoir la VM dans le XAML vous donne une Blendability (voir des exemples de données dans Blend) ce qui est cool, mais le prix à payer est de repasser les informations dans la View. John Papa s'est éloigné de cette approche pour cette raison. J'utilise l'idée de Shawn's Marriage (voir le lien ci-dessus).

HTH -Erik

+0

Hmm .. merci pour le lien. Je le lis maintenant. Je pense que je dois le lire encore quelques fois parce que je ne reçois rien. Shawn dit: «Dans ces deux méthodes, j'ai tendance à ne pas aimer le caractère collant de la vue pour le modèle de vue.Ces deux impliquent une relation un-à-un qui, bien que le cas courant, n'est pas toujours le cas " mais avec View-First les nombreuses vues peuvent être databound à une VM. Une vue peut-elle être liée à plusieurs machines virtuelles? hmmm .. encore une fois, je suppose que si votre V était une simple grille pour vouloir l'avoir lié à différentes machines virtuelles. –

+0

Jusqu'à présent, je suis un fan de garder une relation one-to-one entre Vs et VMs. Ce qui ne veut pas dire que je suis contre une hiérarchie. En d'autres termes, une vue peut contenir des sous-vues possédant chacune sa propre machine virtuelle, ce qui semble fonctionner assez bien. –

+0

Dans notre application, nous avons une vue grille standard qui affiche simplement les lignes de données. Ces données peuvent provenir de ViewModels différents, donc ne pas avoir de sens pour nous. Il est inutile d'avoir plusieurs vues de grille lorsqu'elles sont toutes identiques à l'exception des données qu'il contient. –

0

La façon dont vous avez ici, j'irais avec XAML. Il existe d'autres façons de définir la propriété DataContext. Si vous êtes intéressé, regardez le framework Microsoft CAG pour WPF.

0

J'ai mis la machine virtuelle dans le code parce que ce test de faire de la vue beaucoup plus facile. Justin Ange a un grand message pour cela:

public partial class Page : UserControl 
{ 
    private PageViewModel _viewModel = new PageViewModel(); 

    public PageViewModel ViewModel 
    { 
     get { return _viewModel; } 
     set { _viewModel = value; } 
    } 

    public Page() 
    { 
     InitializeComponent(); 
     this.Loaded += new RoutedEventHandler(Page_Loaded); 
    } 

    void Page_Loaded(object sender, RoutedEventArgs e) 
    { 
     this.DataContext = ViewModel; 
    } 

} 

Je trouve son poste très utile pour l'apprentissage sur les intricasies des tests entourant le modèle MVVM.

http://silverlight.net/blogs/justinangel/archive/2009/02/25/silverlight-unit-testing-rhinomocks-unity-and-resharper.aspx

+0

Merci pour le lien. Je le lis toujours maintenant mais je préfère la méthode de Shawn maintenant. J'ai besoin de passer plus de temps à y penser mais je veux un VM et V. clairement découplés –

4

J'utilise une classe I dub un "écran" qui gère la triade MVVM. J'ai commencé avec un V injecté dans une VM, puis une VM comme ressource dans un V, mais à la fin le concept Screen a fonctionné le mieux pour moi. Cela me permet d'utiliser un V et un VM sans être couplés les uns aux autres. Il extrait également d'autres fonctionnalités de mon cadre de présentation global. Voici le constructeur de ma classe d'écran comme exemple:

public CatalogItemScreen(IUnityContainer container) : base(container) 
    { 
     this.ViewModel = Container.Resolve<ICatalogItemViewModel>(); 
     this.View = Container.Resolve<CatalogItemView>(); 
     this.View.DataContext = this.ViewModel; 
    } 

Notez que VM est créé dans l'écran, le V est créé ici, et les 2 sont liés les uns aux autres. Cet exemple utilise Unity et Prism, mais il n'est pas nécessaire d'y parvenir.

Questions connexes