46 votes

Comment ouvrir une nouvelle fenêtre avec MVVM Light Toolkit

Je suis en utilisant MVVM Light toolkit dans mon application WPF. Je voudrais savoir quelle est la meilleure approche pour l'ouverture d'une nouvelle fenêtre à partir d'une fenêtre existante. J'ai eu ce MainViewModel, qui est responsable de l' MainWindow de mon application. Maintenant, en MainView, sur un clic de bouton, je voudrais ouvrir une deuxième fenêtre sur le dessus de cela. J'ai l' RelayCommmand lié à l' Buttons' Command. Dans l' RelayCommands'méthode, je peux créer un nouvel objet de fenêtre et d'appeler tout simplement Show(), quelque chose comme ceci:

var view2 = new view2()
view2.Show()

mais je ne pense pas que le ViewModel devrait être responsable de la création de la nouvelle - view2 objet. J'ai lu ce post WPF MVVM Obtenir Parent de la VUE MODÈLE où l'Auteur a proposé de passer le message à l' view1 de la viewmodel1 puis view1 devrait créer le nouveau view2. Mais je ne suis pas sûr que veut-il dire par passer le message à l' view1? Comment l' view1 gérer le message? Dans son code derrière ou quoi?

En ce qui concerne, Nabeel

57voto

Matt Casto Points 2102

Le passage d'un message de ViewModel1 à Vue1 moyens d'utiliser les fonctionnalités de messagerie dans le MVVM Light Toolkit.

Par exemple, votre ViewModel1 pourrait avoir une commande appelée ShowView2Command, puis d'envoyer un message à afficher la vue.

public class ViewModel1 : ViewModelBase
{
    public RelayCommand ShowView2Command { private set; get; }

    public ViewModel1() : base()
    {
        ShowView2Command = new RelayCommand(ShowView2CommandExecute);
    }

    public void ShowView2CommandExecute()
    {
        Messenger.Default.Send(new NotificationMessage("ShowView2"));
    }
}

Vue1 serait de vous inscrire pour recevoir des messages dans son code derrière et l'affichage de Vue2 lorsqu'il reçoit le message correct.

public partial class View1 : UserControl
{
    public View1()
    {
        InitializeComponent();
        Messenger.Default.Register<NotificationMessage>(this, NotificationMessageReceived);
    }

    private void NotificationMessageReceived(NotificationMessage msg)
    {
        if (msg.Notification == "ShowView2")
        {
            var view2 = new view2();
            view2.Show();
        }
    }
}

4voto

Scott Silvi Points 1526

Pourquoi pensez-vous aller dans cette voie? Son simple. Si vous remplacez votre bouton avec un toggleButton, ou d'un lien hypertexte, ou tout autre nombre de bouton-comme les contrôles, vous n'avez pas besoin de mettre à jour votre "code behind" - un principe de base de la pattern MVVM. Dans votre nouveau toggleButton (ou autre), vous avez encore jusqu'à la fin de la liaison, exactement la même Commande.

Par exemple, je suis en train de créer un projet pour un client qui veut avoir 2 UI - on va être fondamentalement différentes dans tous les sens, en termes de présentation. Horizontal onglets vs Vertical RadPanelBar (pensez à l'Accordéon) pour la navigation. Ces deux points de vue peuvent pointer vers le même viewModel - lorsqu'un utilisateur clique sur le bon de Travail, onglet 1, il tire les mêmes "WorkOrderCommand" est déclenché dans le Travail en-Tête de Commande dans la barre du panneau.

Dans un modèle code-behind, vous avez le code de deux événements distincts. Ici, vous n'avez qu'à du code.

En outre, il permet à un concepteur à l'aide de Mélange pour créer n'importe quelle forme qu'ils veulent. Tant qu'ils ont les crochets (EventToCommand de contrôle) à la place, moi-même (en tant que développeur) ne pouvais pas moins de soins que le produit final ressemble.

Le couplage est incroyablement puissant.

3voto

Hoshiyar Points 21

Vous pouvez le faire de la manière suivante: créez certains événements, enregistrez-les dans la vue et appelez-les dans la vue modèle.et ouvrez cette fenêtre contextuelle.

Comme cet exemple

 public class Mainclass : MainView
{
    public delegate abc RegisterPopUp(abc A);
    public RegisterPopUp POpUpEvent ;

    public RelayCommand ShowCommand { private set; get; }  


    public void ShowCommand() 
    { 
        ShowCommand("Your parameter");
    } 
}
 

dans la vue MainView mn=new MainView();

Enregistrez l'événement ici comme si mn.POpUpEvent += clic sur le bouton onglet double temps

et dans les registres, la méthode contextuelle à droite du code permettant d'ouvrir la fenêtre contextuelle.

2voto

Nilesh Gule Points 1027

Vous pouvez résumé le point de vue des fonctionnalités spécifiques dans les services à l'aide de interface générique. Dans la couche de la vue, vous pouvez fournir des exemples concrets de ces services et de construire des modèles de vue en utilisant le conteneur IoC et l'Injection de Dépendance technique.

Dans votre cas, vous pouvez construire une interface IWindowManager ou quelque chose de similaire qui dispose de la méthode. Ce peuvent être mises en œuvre dans votre couche de la vue. J'ai écrit un petit billet de blog récemment montrant comment résumé la boîte de dialogue du comportement hors de la vue du modèle. Similaire apporach peut être utilisé pour n'importe quelle interface utilisateur de services connexes tels que la Navigation, MessageBoxes etc.

Ce lien peut être utile pour vous http://nileshgule.blogspot.com/2011/05/silverlight-use-dialogservice-to.html

Bon nombre de personnes utilisent l'approche de la mise à feu des événements à partir d'afficher les modèles qui sont à la base de la vue.cs fichier et à partir de là, la MessageBox ou toute autre INTERFACE utilisateur liés à l'action est effectuée. Personnellement, j'aime l'approche de l'injection de services, parce que vous pouvez fournir plusieurs implémentations d'un même service. Un exemple simple serait la façon dont la navigation est traitée dans Silverlight et Windows Phone 7 applications. Vous pouvez utiliser le même modèle de vue, mais injecter les différentes implémentations du service de la Navigation fondée sur le type d'application.

2voto

Pratz Points 109

À moins que je ne manque le point ici - si je devais utiliser le code derrière, alors pourquoi ne pas directement implémenter l'événement button_click et ouvrir la deuxième vue?

Ce que Bugnion semble suggérer, c’est view1 -> clic sur le bouton -> commande de relais -> viewmodel1 -> message -> view1 -> view1.cs -> ouvrir la vue 2.

De toute façon, vous allez sacrifier la testabilité en écrivant du code derrière, alors pourquoi prendre un aussi long chemin?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X