2012-04-04 5 views
6

Ho bisogno di scrivere una piccola applicazione per leggere un file di configurazione e generare un report con esso. Speravo di usare finalmente MVVM ma è piuttosto difficile iniziare. Oh, sto usando il framework Caliburn.Micro.Passaggio dello stato dell'applicazione tra viewmodels nell'applicazione MVPM WPF

Quindi questo è quello che ho, un guscio (vista primaria che ospita altri punti di vista), che ha un nastro con 3 pulsanti su di esso:

1) Aprire il file 2) Mostra le impostazioni 3) Mostra risultati

E due altre viste, SettingsView e ResultsView con pulsanti per generare ed eliminare un report.

Quindi credo che la struttura di vista sarebbe come questo:

ShellView 
    Ribbon 
     OpenFileButton 
     SettingsButton 
     ResultsButton 
    ContentControl (hosts SettingsView and ResultsView) 

SettingsView 
    CalculateResultsButton 

ResultsView 
    CancelResultsButton 

La parte difficile è questa:

1. "Show settings" button is disabled until a file is opened (via Open file). 
2. "Show results" button is disabled until a report is calculated (via a 
    method in SettingsViewModel). 
3. If a report is calculated, the CalculateResultsButton is disabled and 
    CancelResultsButton is enabled and vice versa. 

Si prega di comunicare come avrei potuto raggiungere questo obiettivo? Non ho idee su quale strategia dovrei andare. Il mio cervello non-MVVM dice che dovrei creare una variabile di stato e poi legare in qualche modo quei pulsanti a quella variabile, ma immagino che non funzionerà in un mondo MVVM, giusto? Qualsiasi esempio di codice sarebbe molto molto apprezzato!

Grazie mille!

risposta

1

Dal momento che si sta utilizzando CM non sarà necessario alcun code-behind. Puoi eliminare i file .xaml.cs se vuoi.

Questo è un esempio piuttosto semplice ma dovrebbe darvi un'idea su come controllare lo stato dei pulsanti. In questo esempio, Open sarà abilitato e gli altri due sono disabilitati. Se si fa clic su Open, Settings è abilitato. Lo stesso accade con Results dopo aver fatto clic su Settings.

Se è necessario un modo per eseguire lo stato globale, è possibile applicare lo stesso concetto immettendo un singleton, SharedViewModel, in ViewModels ei metodi CanXXX possono controllare i valori in SharedViewModel. This è una demo SL di cose diverse, ma una sta iniettando un singleton per condividere i dati, la stessa idea si applica a wpf.

ShellView:

<Window x:Class="CMWPFGuardSample.ShellView" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 

    <Grid Background="White"> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="Auto" /> 
     </Grid.RowDefinitions> 
     <StackPanel Grid.Row="0" 
        Orientation="Horizontal"> 
      <Button x:Name="Open" 
        Content="Open" /> 
      <Button x:Name="Settings" 
        Content="Settings" /> 
      <Button x:Name="Results" 
        Content="Results" /> 
     </StackPanel> 
    </Grid> 

</Window> 

ShellViewModel:

[Export(typeof (IShell))] 
    public class ShellViewModel : PropertyChangedBase, IShell 
    { 
     private bool _isOpen; 
     public bool IsOpen 
     { 
      get { return _isOpen; } 
      set 
      { 
       _isOpen = value; 
       NotifyOfPropertyChange(() => IsOpen); 
       NotifyOfPropertyChange(() => CanSettings); 
      } 
     } 

     private bool _isSettings; 
     public bool IsSettings 
     { 
      get { return _isSettings; } 
      set 
      { 
       _isSettings = value; 
       NotifyOfPropertyChange(() => IsSettings); 
       NotifyOfPropertyChange(() => CanResults); 
      } 
     } 

     public bool IsResults { get; set; } 

     public void Open() 
     { 
      IsOpen = true; 
     } 

     public bool CanSettings 
     { 
      get { return IsOpen; } 
     } 

     public void Settings() 
     { 
      IsSettings = true; 
     } 

     public bool CanResults 
     { 
      get { return IsSettings; } 
     } 

     public void Results() 
     { 
     } 
    } 
0

I comandi MVVM e WPF si adattano perfettamente ai vostri requisiti di "parte difficile" dal momento che hanno integrato il metodo ICommand.CanExecute() che consente di abilitare/disabilitare il pulsante corrispondente in base alla logica personalizzata.

Per utilizzare questa funzione naice, dare un'occhiata prima allo RoutedCommand Class e all'esempio esplicativo su MSDN How to: Enable a Command (vedere sotto frammenti di codice).

E in generale su MVVM, è davvero SEMPLICE! Basta provare e non lasciare senza di esso;) In poche parole - è necessario creare per ogni EntityView.xaml corrispondente EntityViewModel classe e poi appena messo istanza nella di vista DataContext esplicitamente nel codice o utilizzando le associazioni:

var entityViewModel = new EntityViewModel(); 
var view = new EntityView(); 
view.DataContext = entityViewModel; 

MVVM comando e Command.CanExecute binding:

XAML:

<Window x:Class="WCSamples.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="CloseCommand" 
    Name="RootWindow" 
    > 
    <Window.CommandBindings> 
    <CommandBinding Command="ApplicationCommands.Close" 
        Executed="CloseCommandHandler" 
        CanExecute="CanExecuteHandler" 
        /> 
    </Window.CommandBindings> 
    <StackPanel Name="MainStackPanel"> 
    <Button Command="ApplicationCommands.Close" 
      Content="Close File" /> 
    </StackPanel> 
</Window> 

C# code-behind:

// Create ui elements. 
StackPanel CloseCmdStackPanel = new StackPanel(); 
Button CloseCmdButton = new Button(); 
CloseCmdStackPanel.Children.Add(CloseCmdButton); 

// Set Button's properties. 
CloseCmdButton.Content = "Close File"; 
CloseCmdButton.Command = ApplicationCommands.Close; 

// Create the CommandBinding. 
CommandBinding CloseCommandBinding = new CommandBinding(
    ApplicationCommands.Close, CloseCommandHandler, CanExecuteHandler); 

// Add the CommandBinding to the root Window. 
RootWindow.CommandBindings.Add(CloseCommandBinding); 
+0

Non è l'ideale. Caliburn Micro evita tutto il guf di ICommand. http://caliburnmicro.codeplex.com/discussions/250844 –