2012-04-04 11 views
6

Potrzebuję napisać małą aplikację, aby odczytać plik konfiguracyjny i wygenerować z niego raport. Miałem nadzieję, że w końcu skorzystam z MVVM, ale rozpoczęcie gry jest dość trudne. Och, używam frameworka Caliburn.Micro.Przekazywanie stanu aplikacji między modelami w aplikacji WPV MVVM

Więc to, co mam, powłoki (podstawowy pogląd, że odbywają się inne poglądy), który ma taśmę z 3 przycisków na nim:

1) Otwórz plik 2) Pokaż ustawienia 3) Pokaż wyniki

Dwa inne widoki, SettingsView i ResultsView za pomocą przycisków do generowania i usuwania raportu.

Sądzę więc, że struktura widok byłby tak:

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

SettingsView 
    CalculateResultsButton 

ResultsView 
    CancelResultsButton 

Najtrudniejsze jest to:

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. 

Proszę doradzić, w jaki sposób można to osiągnąć? Nie mam pojęcia, jaką strategię powinienem wybrać. Mój mózg nie-MVVM mówi, że powinienem stworzyć zmienną statusu, a potem jakoś związać te przyciski z tą zmienną, ale myślę, że to nie zadziała w świecie MVVM, prawda? Każdy przykład kodu byłby bardzo, bardzo doceniany!

Wielkie dzięki!

Odpowiedz

1

Ponieważ używasz CM nie trzeba będzie dowolny kod z opóźnieniem. Jeśli chcesz, możesz usunąć pliki .xaml.cs.

Jest to całkiem podstawowy przykład, ale powinien dać ci pojęcie, jak kontrolować stan przycisków. W tym przykładzie zostanie włączone Open, a pozostałe dwa zostaną wyłączone. Jeśli klikniesz na Open, Settings jest włączona. To samo dzieje się zpo kliknięciu na Settings.

Jeśli potrzebujesz sposobu na zrobienie stanu globalnego, tę samą koncepcję można zastosować, wstrzykując singleton, SharedViewModel, do ViewModels, a metody CanXXX mogą sprawdzać wartości w SharedViewModel. This jest demo SL różnych rzeczy, ale jeden wstrzykuje singleton do udostępniania danych, ten sam pomysł dotyczy 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

Polecenia MVVM i WPF idealnie pasują do wymagań "trudnej części", ponieważ zostały wbudowane w metodę ICommand.CanExecute(), która umożliwia włączanie/wyłączanie odpowiedniego przycisku w oparciu o niestandardową logikę.

Aby skorzystać z tej funkcji naice, spójrz najpierw na numer RoutedCommand Class i samouczący się przykład na MSDN How to: Enable a Command (zobacz poniżej fragmenty kodu).

I ogólnie o MVVM, to jest naprawdę PROSTE! Po prostu spróbuj tego i nie odejdziesz bez tego;) W kilku słowach - musisz stworzyć dla każdej klasy odpowiadającej klasie EntityViewModel, a następnie po prostu wstaw jej instancję w DataContext widoku jawnie w kodzie lub używając powiązań:

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

MVVM poleceń i Command.CanExecute wiązania:

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> 

kod C# za:

// 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

nie idealny. Caliburn Micro omija wszystkie guzy ICommand. http://caliburnmicro.codeplex.com/discussions/250844 –

Powiązane problemy