2009-09-25 9 views
1

J'ai regardé autour de moi et je n'ai pas encore trouvé beaucoup d'informations à ce sujet. J'ai un projet PRISM mis en place et tout semble fonctionner jusqu'à présent, dans la classe principale d'un module, je crée par programme mes points de vue. Ce que j'essaie de faire est d'obtenir un objet envoyé au viewmodel pour chaque instance de la vue. En ce moment je suis en train de passer l'objet dans le constructeur de vues et faire quelque chose comme ceci:Silverlight PRISM, instancier une vue et transmettre des données dans le viewmodel

public MyView(IUnityContainer container, List<string> myDataObject) 
    { 
     InitializeComponent(); 

     MyViewViewModel vm = LayoutRoot.DataContext as MyViewViewModel; 
     vm.DataObject = myDataObject; 
    } 

Cela provoque une NullReferenceObject pour vm.DataObject, je suppose que le viewmodel n'a pas été correctement instancié à ce stade.

Quelqu'un peut-il me guider sur la façon dont cela devrait être fait? L'objet de données devrait-il être envoyé via la vue?

Merci pour votre temps

Répondre

1

Puisque vous utilisez un conteneur de l'unité, vous pouvez l'utiliser pour passer l'objet DataContext par des vues. Utilisez RegisterInstance lorsque vous créez le DataContext, puis utilisez Resolve dans chaque vue appropriée. Si vous avez plusieurs DataContext, utilisez l'enregistrement nommé.

+0

Salut, merci pour votre réponse, je vois ce que vous entendez sur le conteneur , mais chaque instance est de la même vue et recevra le même type d'objet transmis, alors comment fonctionne l'enregistrement nommé? car la vue ne saurait pas quel contexte elle devra résoudre. De même, comment la résolution du datacontext dans la vue le rend-il disponible au viewmodel? Merci encore –

0

Est-il possible de créer manuellement la vue et son modèle de vue et de définir les objets de données pertinents sur le modèle de vue afin qu'ils puissent être liés aux données, puis les lier ensemble avant de les ajouter à une région?

1

Dans notre code, et dans toutes les vidéos que j'ai regardées, vous le configurez de sorte que la vue prenne en paramètre le ViewModel.

public ThisView(ThisVM vm) 
    { 
     InitializeComponent(); 
     DataContext = vm; 
    } 

Si vous devez passer les choses d'ailleurs, vous pouvez utiliser le EventAggregator pour vous abonner et publier eux.
Un peu comme cela dans l'endroit où vous avez la DataObject:

_EventAggregator.GetEvent<PushModelEvent>().Subscribe(ReceiveModel, true); 

Et comme celui-ci où vous voulez avoir accès (probablement la machine virtuelle):

_EventAggregator.GetEvent<PushModelEvent>().Publish(_Model); 

Il y a encore quelques choses synchrones à traiter, mais, si c'est ce que vous voulez, cela devrait vous aider à démarrer.

1

Dans un exemple d'application que j'ai écrit, j'ai créé une interface qui a été implémentée par la vue. Cette interface a 1 membre, SetViewModel. Cette méthode prend un objet, qui est le ViewModel. ViewModel fournit à View des espaces à lier et gère des commandes.

public interface IDemoView 
{ 
    void SetViewModel(object viewModel); 
} 

la mise en œuvre de cette interface dans la vue réelle ressemble à ceci:

public partial class DemoView : UserControl, IDemoView 
{ 
    public DemoView() 
    { 
     InitializeComponent(); 
    } 

    public void SetViewModel(object viewModel) 
    { 
     DataContext = viewModel; 
    } 
} 

Le constructeur de la vue reste par défaut, et le seul code qui sera jamais dans la codebehind est cette méthode de SetViewModel .

Dans le constructeur de la classe ViewModel, il appelle cette méthode et passe lui-même à la vue.

public IDemoView View { get; private set; } 
private IDemoModel _model; 
public DemoViewModel(IDemoView view, IDemoModel model) 
{    
    _model = model;    
    View = view; 
    View.SetViewModel(this); 
} 

La méthode initialize dans la classe du module enregistre les types avec le UnityContainer et ajoute la vue de la région

public void Initialize() 
{ 
    _container.RegisterType<IDemoView, DemoView>(); 
    _container.RegisterType<IDemoModel, DemoModel>(); 
    _container.RegisterType<IDemoViewModel, DemoViewModel>(); 

    var viewModel = _container.Resolve<IDemoViewModel>(); 

    _regionManager.Regions["MainRegion"].Add(viewModel.View); 
} 
Questions connexes