在MVVM WPF应用程序中的视图模型之间传递应用程序状态
本文关键字:之间 应用 程序状态 模型 视图 WPF MVVM 应用程序 | 更新日期: 2023-09-27 18:29:57
我需要写一个小应用程序来读取配置文件并用它生成一些报告。我希望最终使用MVVM,但这很难开始。哦,我用的是Caliburn。微型框架。
这就是我所拥有的,一个shell(承载其他视图的主视图),它有一个带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世界中是行不通的,对吧?任何代码示例都将不胜感激!
非常感谢!
由于您使用CM,因此不需要任何代码。如果需要,可以删除.xaml.cs文件。
这是一个非常基本的例子,但它应该让您了解如何控制按钮的状态。在本例中,Open
将被启用,其他两个将被禁用。如果单击Open
,则会启用Settings
。单击Settings
后,Results
也会发生同样的情况。
如果您需要一种方法来进行全局状态,可以通过将单例SharedViewModel
注入ViewModels来应用相同的概念,并且CanXXX方法可以检查SharedViewModel
中的值。这是一个不同事物的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()
{
}
}
MVVM和WPF命令完全符合您的"棘手部分"要求,因为它们内置了ICommand.CanExecute()方法,允许基于自定义逻辑启用/禁用相应的按钮。
要使用此naice功能,请首先查看MSDN上的RoutedCommand类和不言自明的示例"如何:启用命令"(请参阅下面的代码片段)。
总的来说,关于MVVM,它真的很简单!试试看,没有它你就不会离开;)简而言之,您必须为每个EntityView.xaml
创建相应的EntityViewModel
类,然后将其实例显式地放在视图的DataContext中,或者使用绑定:
var entityViewModel = new EntityViewModel();
var view = new EntityView();
view.DataContext = entityViewModel;
MVVM命令和命令。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);