web-dev-qa-db-fra.com

Exemple de dialogue WPF MVVM

Quelqu'un a-t-il des exemples d'affichage d'une boîte de dialogue vitrée à l'aide de MVVM (prisme)? - Par exemple, une fenêtre Paramètres de configuration lorsqu'une commande est exécutée.

Tous les exemples que j'ai vus utilisent le motif de médiateur qui va bien, mais ils ont également une référence à la vue dans le modèle de vue qui n'est pas idéal (nous utilisons des dataMPates)

Merci

28
Oll

J'utiliserais un service pour afficher la boîte de dialogue. Le service peut ensuite également relier des vues avec des images de vue.

public interface IDialogService {
    void RegisterView<TView, TViewModel>() where TViewModel:IDialogViewModel;
    bool? ShowDialog(IDialogViewModel viewModel);
}

public interface IDialogViewModel {
    bool CanClose();
    void Close();
}


RegisterView Juste relie le type de vue avec le type de menu de vue. Vous pouvez configurer ces liens dans l'initialisation du module. Ceci est plus simple que d'essayer d'obtenir des modules pour enregistrer des dataMplates dans la couche supérieure de votre application.

ShowDialog montre la vue que vous souhaitez afficher. Il retourne vrai, faux et null pour fermer juste comme le Window.ShowDialog méthode. La mise en œuvre crée simplement une nouvelle vue de type TView à partir de votre conteneur, le raccroche jusqu'à la vue fournie et le montre.

IDialogViewModel fournit un mécanisme pour la vision de la vérification et d'annuler la fermeture de la boîte de dialogue.

J'ai une fenêtre de dialogue standard, avec un contrôle de contenu. Lorsque ShowDialog est appelé, il crée une nouvelle boîte de dialogue standard, ajoute la vue sur la commande de contenu, raccroche la vue de la vue et l'affiche. La boîte de dialogue standard contient déjà des touches [OK] et [Annuler] avec la logique appropriée pour appeler les bonnes méthodes à partir de IDialogViewModel.

23

Je suis d'accord, que l'utilisation de Service pour afficher la boîte de dialogue selon MVVM Modèle est la solution la plus simple. Mais, je me suis également demandé, s'il y a 3 assemblages dans mon modèle de projet, la viewModel, la vue et selon MVVM Motif Assembly ViewModel a une référence au modèle et de la visualisation à la fois modèle et viewModel où dois-je placer la classe Dialogservice? Si je vais placer un dans l'assembly de viewmodel - je n'ai aucune occasion de créer une instance DialogView; D'autre part, si je vais placer du dialogue à l'assemblée, comment je devrais l'injecter dans ma classe de viewModel?

Donc, je serais recommandé à regarder scénarios avancés MVVM avec prisme Partie: Utilisation d'objets de demande d'interaction

A l'exemple de cette approche:

DialogViewModelBase

public abstract class DialogViewModelBase : ViewModelBase
{
    private ICommand _ok;

    public ICommand Ok
    {
        get { return _ok ?? (_ok = new DelegateCommand(OkExecute, CanOkExecute)); }
    }

    protected virtual bool CanOkExecute()
    {
        return true;
    }

    protected virtual void OkExecute()
    {
        _isSaved = true;
        Close = true;
    }

    private ICommand _cancel;

    public ICommand Cancel
    {
        get 
        {
           return _cancel ?? (_cancel = new DelegateCommand(CancelExecute, CanCancelExecute));
        }
    }

    protected virtual bool CanCancelExecute()
    {
        return true;
    }

    protected virtual void CancelExecute()
    {
        Close = true;
    }

    private bool _isSaved = false;
    public bool IsSaved
    {
        get { return _isSaved; }
    }

    private bool _close = false;

    public bool Close
    {
        get { return _close; }
        set
        {
            _close = value;
            RaisePropertyChanged(() => Close);
        }
    }
}

CreateSerserstoryViewModel:

public class CreateUserStoryViewModel : DialogViewModelBase
{
    private string _name = String.Empty;

    public string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            RaisePropertyChanged(() => Name);
        }
    }
}

CreateSerSertoryRequest

private InteractionRequest<Notification> _createUserStoryRequest;
public InteractionRequest<Notification> CreateUserStoryRequest
{
    get
    {
        return _createUserStoryRequest ?? (_createUserStoryRequest = new InteractionRequest<Notification>());
    }
}

Catégorie de CreateSerTory

private void CreateUserStoryExecute()
{
    CreateUserStoryRequest.Raise(new Notification()
    {
        Content = new CreateUserStoryViewModel(),
        Title = "Create User Story"
    }, 
    notification =>
                 {
                      CreateUserStoryViewModel createUserStoryViewModel =
                               (CreateUserStoryViewModel)notification.Content;
                      if (createUserStoryViewModel.IsSaved)
                      {
                         _domainContext.CreateUserStory(
new UserStory(){ Name = createUserStoryViewModel.Name, });
                      }
                 });
}

xaml:

<!--where xmlns:i="http://schemas.Microsoft.com/expression/2010/interactivity"
          xmlns:ir="clr-namespace:Microsoft.Practices.Prism.Interactivity.InteractionRequest;Assembly=Microsoft.Practices.Prism.Interactivity"-->

<i:Interaction.Triggers>
  <ir:InteractionRequestTrigger SourceObject="{Binding CreateUserStoryRequest}">
    <ir:PopupChildWindowAction>
      <ir:PopupChildWindowAction.ChildWindow>
        <view:CreateUserStory />
      </ir:PopupChildWindowAction.ChildWindow>
    </ir:PopupChildWindowAction>
  </ir:InteractionRequestTrigger>
</i:Interaction.Triggers>
3
Vladimir Dorokhov

Alors que j'ai compris votre commentaire ci-dessus, la question ne se pose pas tellement de montrer les dialogues comme à leur cacher. Il y a deux façons de résoudre ce problème:

  1. Utilisez une boîte de dialogue standard pour implémenter la vue. Cela nécessiterait d'avoir un moyen de communication de manière lâche entre View et ViewModel de manière à ce que ViewModel puisse notifier la vue qu'il est correct de se fermer sans avoir une référence à une vue.

    Il existe plusieurs cadres qui permettraient de le faire - les agrégateurs d'événements de Prism seraient l'un d'entre eux. Dans ce scénario, la vue s'abonnerait à un événement (par exemple, myDialogResultvalidated) et à la réception de l'événement, il définirait le dialogue de dialogrutisme. ViewModel (dans sa Savecommand) déclencherait l'événement si la validation a été réussie.

  2. N'utilisez pas la fenêtre de dialogue standard pour implémenter la vue. Cela nécessiterait d'avoir une superposition qui imiterait efficacement la modalité.

    Dans ce scénario, la visibilité de la vue et de la superposition sera liée à la propriété ISvisible de ViewModel qui serait définie en conséquence par la mise en œuvre de Savecommand, ou chaque fois que la viewModel doit montrer la vue.

La première approche nécessiterait d'avoir un peu de code dans Code-Derrière, nécessite l'ajout d'événements globaux et (sans doute) est moins mvvm-ish. La deuxième approche nécessiterait la mise en œuvre (ou l'utilisation de la mise en œuvre de quelqu'un d'autre) de la superposition, mais ne nécessitera pas de code dans Code-derrière, ne nécessitera pas d'événement mondial, et est (argument) plus MVVM-ISH .

2
PL.

Ce n'est pas un prisme, mais cela Demo MVVM a une boîte de dialogue d'options entièrement MVVM.

0
Scott Whitlock

Vous pourriez être intéressé par l'exemple d'application suivante:

(( http://compositeextensions.codeplex.com

Il utilise le prisme2 avec le motif de présentationModel (AKA MVVM). L'exemple d'application contient une boîte de dialogue modale.

0
jbe