MVVM – 事件
事件是一种对状态变化作出反应的编程结构,可通知已注册通知的任何端点。事件主要用于通过鼠标和键盘通知用户输入,但其用途并不仅限于此。每当检测到状态更改时(可能是在加载或初始化对象时),都可以触发事件以提醒任何感兴趣的第三方。
在使用 MVVM(模型-视图-视图模型)设计模式的 WPF 应用程序中,视图模型是负责处理应用程序的表示逻辑和状态的组件。
视图的代码隐藏文件不应包含任何代码来处理从任何用户界面 (UI) 元素(例如按钮或组合框)引发的事件,也不应包含任何特定于域的逻辑。
理想情况下,视图的代码隐藏仅包含一个调用 InitializeComponent 方法的构造函数,以及可能包含一些其他代码来控制或与视图层交互,这些代码在 XAML 中表达起来很困难或效率低下,例如复杂的动画。
让我们看一个应用程序中按钮单击事件的简单示例。以下是 MainWindow.xaml 文件的 XAML 代码,您将在其中看到两个按钮。
<Window x:Class = "MVVMHierarchiesDemo.MainWindow" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local = "clr-namespace:MVVMHierarchiesDemo" xmlns:views = "clr-namespace:MVVMHierarchiesDemo.Views" xmlns:viewModels = "clr-namespace:MVVMHierarchiesDemo.ViewModel" mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "525"> <Window.DataContext> <local:MainWindowViewModel/> </Window.DataContext> <Window.Resources> <DataTemplate DataType = "{x:Type viewModels:CustomerListViewModel}"> <views:CustomerListView/> </DataTemplate> <DataTemplate DataType = "{x:Type viewModels:OrderViewModel}"> <views:OrderView/> </DataTemplate> </Window.Resources> <Grid> <Grid.RowDefinitions> <RowDefinition Height = "Auto" /> <RowDefinition Height = "*" /> </Grid.RowDefinitions> <Grid x:Name = "NavBar"> <Grid.ColumnDefinitions> <ColumnDefinition Width = "*" /> <ColumnDefinition Width = "*" /> <ColumnDefinition Width = "*" /> </Grid.ColumnDefinitions> <Button Content = "Customers" Command = "{Binding NavCommand}" CommandParameter = "customers" Grid.Column = "0" /> <Button Content = "Order" Command = "{Binding NavCommand}" CommandParameter = "orders" Grid.Column = "2" /> </Grid> <Grid x:Name = "MainContent" Grid.Row = "1"> <ContentControl Content = "{Binding CurrentViewModel}" /> </Grid> </Grid> </Window>
您可以看到,上面的 XAML 文件中未使用按钮 Click 属性,但使用 Command 和 CommandParameter 属性来在按下按钮时加载不同的视图。现在您需要在 MainWindowViewModel.cs 文件中定义命令实现,而不是在 View 文件中定义。以下是完整的 MainWindowViewModel 实现。
using MVVMHierarchiesDemo.ViewModel; using MVVMHierarchiesDemo.Views; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace MVVMHierarchiesDemo { class MainWindowViewModel : BindableBase { public MainWindowViewModel() { NavCommand = new MyICommand<string>(OnNav); } private CustomerListViewModel custListViewModel = new CustomerListViewModel(); private OrderViewModel orderViewModelModel = new OrderViewModel(); private BindableBase _CurrentViewModel; public BindableBase CurrentViewModel { get { return _CurrentViewModel; } set { SetProperty(ref _CurrentViewModel, value); } } public MyICommand<string> NavCommand { get; private set; } private void OnNav(string destination) { switch (destination) { case "orders": CurrentViewModel = orderViewModelModel; break; case "customers": default: CurrentViewModel = custListViewModel; break; } } } }
从 BindableBase 类派生所有 ViewModel。编译并执行上述代码后,您将看到以下输出。
如您所见,我们在 MainWindow 上仅添加了两个按钮和一个 CurrentViewModel。现在,如果您单击任何按钮,它将导航到该特定视图。让我们单击"Customers"按钮,您将看到显示了 CustomerListView。
我们建议您分步执行上述示例,以便更好地理解。