2009-08-24 12 views
7

Ho implementato il mio messaggio di errore MVVM come una finestra di messaggio che sottoscrive messaggi di errore tramite una classe mediatore, in modo che altri viewmodels possano notificarlo in caso di errori.La finestra di errore mostra modal in MVVM WPF

Quando si verifica un errore, ho impostato l'attributo visibilità in viewmodel su Visible, per visualizzare la finestra di errore. Questo è tutto legato nella finestra Error da viewmodel.

Tuttavia, questa finestra NON è modale! Ho bisogno di mostrarlo come una finestra di dialogo e non solo di impostare la visibilità su true: c'è qualche tipo di legame che posso fare, anche se devo estendere la funzionalità della finestra? Preferisco non rompere MVVM se posso evitarlo.

Grazie!

+0

Forse ignorare qualche gestore OnvisibilityChanged nel code-behind della finestra di errore? – bluebit

risposta

3

La divisione View/ViewModel ha lo scopo di dividere l'aspetto dalla funzionalità. Sono fermamente convinto che Window sia funzionalità e sembra in uno. Per esempio, cosa succede se nel vostro ErrorMessageViewModel, hai avuto questo codice che viene eseguito quando ci sono errori:

class WindowViewModel : Window 
{ 
} 

. 
. 
. 

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

Così il contenuto della finestra di dialogo è il ViewModel per la vostra lista degli errori. Definisci la tua vista come un modello di dati che si applica automaticamente alla lista errori ViewModel.

Non sembra MVVM?

Il fatto è che la classe Window è un ViewModel per la finestra che vedi sullo schermo. Modificando le proprietà dell'oggetto Window, influisce sulla "vista" proprio come se le proprietà di WindowView fossero associate a un WindowViewModel. L'unica cosa che manca è la possibilità di "restyling" della finestra usando WPF, e non importa quanto tu provi a implementarla, non sarai in grado di farlo. L'utente può ridimensionare una finestra modificando il tema del desktop, ma non ne hai il controllo. Il meglio che puoi fare è spegnere il chrome e/o renderlo a schermo intero.

+0

Come andresti sull'unità testando un ViewModel come questo? – russau

+0

@russau: Si potrebbe supporre che Microsoft abbia fatto test unitari ragionevoli sulla classe Window stessa. È certamente possibile scrivere test unitari che esercitano qualsiasi funzionalità aggiuntiva che si scrive nella classe WindowViewModel stessa. –

2

Potete trovare un esempio di come le finestre (non importa se sono modali o meno) sono mostrati, nell'esempio ViewModel di questo progetto:

WPF Application Framework (WAF)

http://waf.codeplex.com

0

nel mio recente post sul blog è possibile trovare soluzione semplice per la modali finestre di dialogo e finestre di messaggio in MVVM per Silverlight, ma questo può essere semplicemente riutilizzato in WPF:

Modal dialogs with MVVM and Silverlight 4

+0

Ho postato un commento al tuo articolo, è ancora in attesa di moderazione secondo giorno. Quindi duplicherò la mia risposta qui: "Si asserisce che si tratta di una decisione agnostica della piattaforma, ma per quanto ne so, la finestra WPF ha il metodo ShowDialog inteso per mostrarsi come finestra di dialogo modale. metodo. Questo non porterebbe a un comportamento modale, vero? –

1

Sto anche lavorando su un progetto MVVM in cui ho bisogno di finestre di dialogo modali o caselle di messaggio. Ho trovato il seguente modo di risolverlo:

Il software utilizza solo una finestra. L'elemento radice di layout è una griglia senza righe o colonnedefinizioni. La griglia ha tre figli:

  1. Un dockpanel che contiene tutte le solite cose come menu, viste a schede, barra di stato e così via.
  2. Una griglia con uno sfondo grigio e un'opacità del 50%. Viene utilizzato come velo per coprire il dockpanel quando è attiva una casella modale. La griglia del velo di solito è crollata.
  3. Una griglia che contiene visualizzazioni modali, di solito è compressa.

Il viewmodel per la finestra principale ha un membro chiamato Modal. Se questo è nullo, le due griglie per l'uso modale vengono compresse tramite il databinding e un convertitore per Visibility.Collapsed.

Quando il programma desidera visualizzare ad esempio una finestra di messaggio modale, un MessageBoxViewModel viene istanziato e assegnato a MainViewModel.Modal. MessageBoxViewModel ha un comando per un pulsante OK. Questo comando genera un evento che imposta nuovamente MainViewModel.Modal su null.

La griglia del velo occlude il DockPanel principale, in modo che nessun controllo esterno al controllo Modal accetti l'input.

Il tuo programma può eseguire un messagepump fino a quando viene premuto OK, oppure il comando OK può attivare il successivo. Esistono molti modi per risolvere esigenze diverse, ma la soluzione ModelView Model dovrebbe supportarli.

Ritengo che questo sia un buon modello della vista in modalità modale come si può sperare.

1

Ho creato un comportamento per legare alcune finestre di dialogo modali al comando.

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

sto usando lo stesso metodo di Scott Whitlock.

c'è solo un altro importante proprietà per impostare:

class ModalDialog: Window 
{ 
} 

. 
. 
. 

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

dlg.ShowDialog();