39 votes

"Êtes-vous sûr?" instructions. Une partie du ViewModel ou purement la vue?

J'ai joué avec où les mettre "êtes-vous sûr?", tapez invite dans mon application WPF, MVVM.

Je suis penchée vers la pensée que ces derniers sont purement une partie de la Vue. Si le ViewModel expose DeleteCommand, alors je m'attends à ce que la commande pour supprimer immédiatement.

L'intégration de ces invites dans le ViewModel, il aurait à exposer un distinct RequestDeleteCommand, un DeletePromptItem de la propriété de liaison de l'invite de contre, et qui pourrait également doubler comme un déclencheur pour afficher l'invite de commandes.

Même avec cela, il n'y a rien d'arrêt d'une unité de test en appelant DeleteCommand directement, à moins que j'ai mis la logique spécifique dans le ViewModel pour exiger DeletePromptItem pour correspondre à l'élément fourni en argument DeleteCommand.

Cependant, tout cela semble juste comme le bruit dans le ViewModel pour moi. L'invite est plus un problème d'interface utilisateur pour se prémunir contre toute erreur de clic etc. Pour moi, cela suggère qu'il devrait être dans la vue avec un confirmé invite l'appel de la DeleteCommand.

Toutes les pensées?

16voto

Jon Points 194296

Les invites ne devrait vraiment pas être une partie de ce Dernier, mais cela ne veut pas nécessairement dire que la meilleure solution est de coder en dur dans la Vue (même si c'est très raisonnable première approche).

Il y a deux solutions, que je sais de ce qui peut réduire le couplage entre la Vue et le ViewModel: l'utilisation d'une interaction de service, et le tir de l'interaction des demandes. Les deux sont très bien expliqué ici; vous voudrez peut-être jeter un coup d'oeil.

L'idée générale est que vous avez résumé la façon asynchrone les interactions sont de fait et de travailler avec quelque chose de plus semblable à l'événement à base de logique alors que dans le même temps, permettant à ce Dernier d'exprimer qu'il veut interagir avec l'utilisateur dans le cadre d'une opération, le résultat net est que vous pouvez documenter cette interaction et de l'unité de test.

Edit: je dois ajouter que j'ai exploré à l'aide de Prism 4 interaction avec les demandes dans un prototype de projet et j'ai été très heureux avec les résultats (avec un peu de code de la structure de passe vous pouvez même spécifier ce qui se passe sur une interaction spécifique de demande entièrement en XAML!). J'aimerais donner quelques extraits, mais il faudra attendre demain.

8voto

BoltClock Points 249668

Cependant, tout cela semble juste comme le bruit dans le ViewModel pour moi. L'invite est plus un problème d'interface utilisateur pour se prémunir contre toute erreur de clic etc. Pour moi, cela suggère qu'il devrait être dans la vue avec un confirmé invite l'appel de la DeleteCommand.

Je suis d'accord; les invites comme cela devrait être géré dans la vue, car en fin de compte le point de vue est que l'utilisateur de voir et d'interagir avec, et non pas le modèle de vue. Une fois que votre vue a obtenu la confirmation de l'utilisateur que l' DeleteCommand doit être invoquée, puis aller de l'avant et à l'appeler dans votre modèle de vue.

La façon dont je le vois, les tests unitaires n'ont pas vraiment de chose à voir avec l'interaction de l'utilisateur, sauf si vous faites des tests de la vue elle-même.

6voto

Daniel Hilgarth Points 90722

À mon avis, invitant l'utilisateur se compose de deux parties:

  1. La logique qui détermine si oui ou non l'invite de commandes devrait être montré et ce qui doit être fait avec le résultat
  2. Le code qui affiche l'invite

La partie 2 n'est manifestement pas leur place dans le ViewModel.
Mais la Partie 1 n'appartiennent il.

Pour faire cette séparation possible, j'utilise un service qui peut être utilisé par le ViewModel et pour lequel je peux fournir une implémentation spécifique à l'environnement, je suis en (WPF, Silverlight, WP7).

Cela conduit à un code comme ceci:

interface IMessageBoxManager
{
    MessageBoxResult ShowMessageBox(string text, string title,
                                    MessageBoxButtons buttons);
}

class MyViewModel
{
    IMessageBoxManager _messageBoxManager;

    // ...

    public void Close()
    {
        if(HasUnsavedChanges)
        {
            var result = _messageBoxManager.ShowMessageBox(
                             "Unsaved changes, save them before close?", 
                             "Confirmation", MessageBoxButtons.YesNoCancel);
            if(result == MessageBoxResult.Yes)
                Save();
            else if(result == MessageBoxResult.Cancel)
                return; // <- Don't close window
            else if(result == MessageBoxResult.No)
                RevertUnsavedChanges();
        }

        TryClose(); // <- Infrastructure method from Caliburn Micro
    }
}

Cette approche peut facilement être utilisé non seulement pour afficher une boîte de message mais aussi pour montrer aux autres fenêtres, comme expliqué dans cette réponse.

3voto

ebeeb Points 1584

Je suggère de le faire via un service qui gère les fenêtres modales. J'ai fait face à ce problème il y a pas mal de temps non plus. Ce billet de blog m'a beaucoup aidé.

Même s'il s'agit d'un article silverlight, il ne devrait pas trop différer par rapport à wpf.

0voto

Nicolas Repiquet Points 4411

Je résous ce type de problème en utilisant le modèle EventAggregator .

Vous pouvez le voir expliqué ici

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