2009-08-24 6 views
7

J'ai mis en œuvre mon message d'erreur MVVM en tant que boîte de dialogue de message souscrite à des messages d'erreur via une classe médiateur, afin que d'autres modèles puissent l'avertir en cas d'erreur.Affichage de la fenêtre d'erreur modale dans MVVM WPF

Lorsqu'une erreur se produit, je mets l'attribut visibility dans le viewmodel à Visible, pour afficher la fenêtre d'erreur. Tout est lié dans la fenêtre d'erreur du viewmodel.

Cependant, cette fenêtre n'est pas modale! J'ai besoin de le montrer comme une boîte de dialogue et pas seulement de définir la visibilité à vrai - y at-il une sorte de liaison que je peux faire, même si je dois étendre la fonctionnalité de la fenêtre? Je préfère ne pas casser MVVM si je peux l'éviter.

Merci!

+0

outrepasser Peut-être un gestionnaire OnvisibilityChanged dans le code-behind de la fenêtre d'erreur? – bluebit

Répondre

3

La division View/ViewModel est conçue pour diviser l'aspect de la fonctionnalité. Je crois fermement que la fenêtre est la fonctionnalité et l'apparence en une seule. Par exemple, si dans votre ErrorMessageViewModel, vous aviez le code qui exécute quand il y a des erreurs:

class WindowViewModel : Window 
{ 
} 

. 
. 
. 

WindowViewModel newDialog = new WindowViewModel(); 
newDialog.Content = myErrorListViewModel; 
newDialog.Parent = mainWindowViewModel; 
newDialog.ShowDialog(); 

Ainsi, le contenu de la boîte de dialogue est le ViewModel pour votre liste d'erreurs. Définissez votre vue en tant que modèle de données qui s'applique automatiquement à la liste d'erreurs ViewModel.

Cela ne ressemble-t-il pas à MVVM?

Le fait est que la classe Window est un ViewModel pour la fenêtre que vous voyez à l'écran. En modifiant les propriétés de l'objet Window, il affecte la "vue" comme si les propriétés de WindowView étaient liées à un WindowViewModel. La seule chose qui manque est la possibilité de "restyle" la fenêtre en utilisant WPF, et peu importe comment vous essayez de l'implémenter, vous ne serez pas en mesure de le faire. L'utilisateur peut modifier une fenêtre en modifiant son thème de bureau, mais vous n'en avez pas le contrôle. Le mieux que vous pouvez faire est d'éteindre le chrome et/ou de le faire en plein écran.

+0

Comment iriez-vous sur les tests unitaires d'un ViewModel comme celui-ci? – russau

+0

@russau: On pourrait supposer que Microsoft a fait des tests unitaires raisonnables sur la classe Window elle-même. Vous pouvez certainement écrire des tests unitaires qui exercent toute fonctionnalité supplémentaire que vous écrivez dans la classe WindowViewModel elle-même. –

2

Vous trouverez un exemple comment les fenêtres (ne pas d'importance si elles sont modales ou non) sont indiqués dans l'exemple ViewModel de ce projet:

cadre WPF Application (WAF)

http://waf.codeplex.com

0

dans mon récent blog, vous pouvez trouver une solution simple pour modales et Dialogs boîtes de message dans MVVM pour Silverlight, mais cela peut être simplement réutilisé dans WPF:

Modal dialogs with MVVM and Silverlight 4

+0

J'ai posté un commentaire à votre article, il attend toujours la modération deuxième jour. Donc je vais dupliquer ma réponse ici: "Vous affirmez que c'est une décision agnostique de la plate-forme, mais pour autant que je sache, la fenêtre WPF a la méthode ShowDialog destinée à s'afficher comme un dialogue modal. Cela ne conduirait pas à un comportement modal, n'est-ce pas? " –

1

Je travaille également sur un projet MVVM où j'ai besoin de boîtes de dialogue modales ou de boîtes de message. J'ai trouvé la façon de le résoudre:

Le logiciel utilise une seule fenêtre. L'élément racine de mise en page est une grille sans définition de ligne ou de colonne. La grille a trois enfants:

  1. Un dockpanel qui contient tous les trucs habituels comme les menus, les onglets, la barre d'état, etc.
  2. Une grille qui a un fond gris et une opacité de 50%. Ceci est utilisé comme un voile pour couvrir le dockpanel lorsqu'une boîte modale est en vigueur. La grille de voile est généralement effondrée.
  3. Une grille contenant des vues modales, elle est généralement réduite.

Le modèle de vue pour la fenêtre principale a un membre appelé Modal. Si cela est nul, les deux grilles pour une utilisation modale sont réduits grâce à la liaison de données et un convertisseur pour Visibility.Collapsed.

Lorsque le programme veut afficher par exemple une boîte de message modal, un MessageBoxViewModel est instancié et affecté à MainViewModel.Modal. Le MessageBoxViewModel a une commande pour un bouton OK. Cette commande déclenche un événement qui définit à nouveau le MainViewModel.Modal à null.

La grille de voile ferme le DockPanel principal, de sorte qu'aucun contrôle en dehors du contrôle Modal n'accepte d'entrée.

Votre programme peut exécuter un messagepump jusqu'à ce que vous appuyez sur OK, ou le OK de commande peut déclencher l'autre. Il existe plusieurs façons de résoudre différents besoins, mais la solution Model-ModelView devrait les supporter.

Je pense que c'est aussi bon modèle de la vue dans le mode modal que l'on peut espérer.

1

J'ai fait une behhavior pour attacher des boîtes de dialogue modales à la commande.

http://www.clr-namespace.com/post/MVVMModal-dialog-before-running-Command.aspx

<Confirm:Confirm IsConfirm="{Binding ElementName=checkBoxConfirm, Path=IsChecked}" 
Command="{Binding Path=ButtonCommand}" 
CommandParameter="{Binding ElementName=textBoxParameter, Path=Text}" 
ConfirmMessage="Are you sure you want to fire the command?" 
ConfirmCaption="Question" > 
</Confirm:Confirm> 
0

J'utilise la même méthode que Scott Whitlock.

il y a juste une propriété plus important de définir:

class ModalDialog: Window 
{ 
} 

. 
. 
. 

var dlg = new ModalDialog { 
    Content = viewModelName, 
    **TopMost = true,** 
    Parent = mainWindowViewModel 
}; 

dlg.ShowDialog(); 
Questions connexes