2012-04-04 25 views
6

我需要編寫一個小應用程序來讀取配置文件並使用它生成一些報告。我希望最終能夠使用MVVM,但開始起來相當棘手。哦,我正在使用Caliburn.Micro框架。在MVVM WPF應用程序的視圖模型之間傳遞應用程序狀態

因此,這是我,其上具有與3個按鈕的帶狀的殼(承載其他視圖主視圖):

1)打開文件 2)顯示設定 3)上顯示結果

和其他兩個視圖,SettingsView和ResultsView帶有按鈕來生成和刪除報告。

所以我猜這個視圖結構會是這樣:

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

SettingsView 
    CalculateResultsButton 

ResultsView 
    CancelResultsButton 

棘手的部分是這樣的:

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. 

請告訴我怎麼能做到這一點?我不知道我應該採取什麼策略。我的非MVVM思維大腦說,我應該創建一個狀態變量,然後以某種方式將這些按鈕綁定到該變量,但我想這不會在MVVM世界中工作,對吧?任何代碼示例都會非常非常感謝!

非常感謝!

回答

1

由於您使用的CM你不需要任何代碼隱藏。如果需要,可以刪除.xaml.cs文件。

這是一個非常基本的例子,但它應該給你一個關於如何控制按鈕狀態的想法。在這個例子中,Open將被啓用,另外兩個被禁用。如果您點擊Open,則啓用Settings。一旦Settings被點擊,Results也會發生同樣的情況。

如果您需要一種執行全局狀態的方法,則可以通過在ViewModels中注入一個單例SharedViewModel來應用相同的概念,並且CanXXX方法可以檢查SharedViewModel中的值。 This是一個不同的東西的SL演示,但其中一個是注入一個singleton來共享數據,相同的想法適用於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

MVVM和WPF命令完全符合您的「棘手的部分」要求,因爲已經內置了ICommand.CanExecute()方法,該方法允許基於自定義邏輯啓用/禁用相應的按鈕。

要使用此naice功能,請首先看RoutedCommand Class和MSDN How to: Enable a Command(請參閱下面的代碼片段)上的自解釋示例。

一般來說關於MVVM,它真的很簡單!試試吧,你不會離開它;)在幾句話 - 你必須爲每個EntityView.xaml相應EntityViewModel類,然後只是把它的實例在視圖的DataContext的顯式代碼或使用綁定:

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

MVVM指揮Command.CanExecute綁定:

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#代碼隱藏:

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

不理想。 Caliburn Micro避免了所有的ICommand和Guff。 http://caliburnmicro.codeplex.com/discussions/250844 – 2012-04-05 01:01:36

相關問題