2012-04-04 41 views
6

Tôi cần viết một ứng dụng nhỏ để đọc tệp cấu hình và tạo một số báo cáo với nó. Tôi đã hy vọng cuối cùng sẽ sử dụng MVVM nhưng nó khá khó khăn để bắt đầu. Ồ, tôi đang sử dụng khung Caliburn.Micro.Chuyển trạng thái ứng dụng giữa các chế độ xem trong ứng dụng MVVM WPF

Vì vậy, đây là những gì tôi có, một vỏ (xem chính mà tổ chức quan khác) mà có một dải ruy băng với 3 nút trên nó:

1) Mở file 2) Hiển thị các thiết lập 3) Hiển thị kết quả

Và hai chế độ xem khác, SettingsView và ResultsView có các nút để tạo và xóa báo cáo.

Vì vậy, tôi đoán cấu trúc xem sẽ như thế này:

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

SettingsView 
    CalculateResultsButton 

ResultsView 
    CancelResultsButton 

Phần khó khăn là thế này:

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. 

Xin cho biết làm thế nào tôi có thể đạt được điều này? Tôi không có ý tưởng chiến lược nào tôi nên đi. My-MVVM-suy nghĩ-não nói rằng tôi nên tạo ra một biến trạng thái và sau đó bằng cách nào đó ràng buộc các nút để biến đó, nhưng tôi đoán rằng sẽ không làm việc trong một thế giới MVVM, phải không? Bất kỳ ví dụ mã nào sẽ rất được đánh giá rất cao!

Rất cám ơn!

Trả lời

1

Vì bạn đang sử dụng CM bạn sẽ không cần bất kỳ code-behind. Bạn có thể xóa các tệp .xaml.cs nếu muốn.

Đây là một ví dụ khá cơ bản nhưng nó sẽ cung cấp cho bạn một ý tưởng về cách kiểm soát trạng thái của các nút. Trong ví dụ này, Open sẽ được bật và hai thiết bị còn lại sẽ bị tắt. Nếu bạn nhấp vào Open, Settings được bật. Điều tương tự cũng xảy ra với Results khi nhấp Settings.

Nếu bạn cần một cách để làm trạng thái toàn cầu, cùng một khái niệm có thể được áp dụng bằng cách tiêm một singleton, SharedViewModel, vào ViewModels và các phương thức CanXXX có thể kiểm tra các giá trị trong SharedViewModel. This là bản demo SL về những thứ khác nhau nhưng một là tiêm một singleton để chia sẻ dữ liệu, ý tưởng tương tự áp dụng trong 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 và WPF lệnh hoàn toàn phù hợp "phần khó khăn" của bạn yêu cầu kể từ khi đã xây dựng được trong ICommand.CanExecute() phương pháp mà cho phép bật/tắt nút tương ứng dựa trên logic tùy chỉnh.

Để sử dụng tính năng naice này, hãy xem trước RoutedCommand Class và ví dụ tự giải thích trên MSDN How to: Enable a Command (xem đoạn mã bên dưới).

Và nói chung về MVVM, nó thực sự là SIMPLE! Chỉ cần cố gắng nó và bạn sẽ không để lại mà không có nó;) Trong vài từ - bạn phải tạo cho mỗi EntityView.xaml tương ứng EntityViewModel lớp và sau đó chỉ cần đặt thể hiện của nó trong DataContext của Xem hoặc rõ ràng trong mã hoặc sử dụng các ràng buộc:

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

lệnh MVVM và Command.CanExecute bindings:

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# mã sau:

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

Không lý tưởng. Caliburn Micro tránh tất cả guff của ICommand. http://caliburnmicro.codeplex.com/discussions/250844 –

Các vấn đề liên quan