Passing application state between view modes in an MVVM WPF application

I need to write a small application to read the configuration file and generate some report with it. I was hoping to finally use MVVM, but it's pretty hard to get started. Oh, I'm using Caliburn.Micro.

So, this is what I have, a shell (the main view, on which other views are placed), on which there is a ribbon with 3 buttons:

1) Open file 2) Show settings 3) Show results

And two more views, SettingsView and ResultsView with buttons for creating and deleting a report.

So, I assume that the presentation structure will be like this:

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

The hard part:

 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. 

Please let me know how I could achieve this. I have no idea what strategy I should go for. My brain, other than MVVM, says that I have to create a status variable and then somehow bind these buttons to this variable, but I suppose that won't work in the MVVM world, right? Any code sample would be very much appreciated!

Many thanks!

+6
source share
2 answers

Since you are using CM, you will not need the code. You can delete .xaml.cs files if you want.

This is a fairly simple example, but it should give you an idea of ​​how to control the state of the buttons. In this example, Open will be activated, and the other two will be disabled. If you click Open , Settings will be turned on. The same thing happens with Results after clicking Settings .

If you need a way to make global state, you can apply the same concept by entering singleton, SharedViewModel , in ViewModels, and CanXXX methods can check values ​​in SharedViewModel . This is a demonstration of SL of different things, but one of them introduces singleton for data exchange, the same idea is applied in 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() { } } 
+1
source

MVVM and WPF commands perfectly meet your requirements of the "difficult part", because they are built into the ICommand.CanExecute () method, which allows you to enable / disable the corresponding ones based on user logic.

To use this naive look feature, first take a look at the RoutedCommand class and explanatory example on MSDN How to enable a command (see code snippets below).

And generally about MVVM, it's really SIMPLE! Just try it and you won’t be left without it;) In a few words you need to create an EntityView.xaml class for each EntityViewModel , and then just put its instance in the ViewConttext as explicitly in the code or using the bindings:

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

MVVM Command and Command.CanExecute Commands:

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

Source: https://habr.com/ru/post/912419/


All Articles