[7.1updated]这一节除了基础app部分,并无什么变化html
先看下微软官方的说明:c#
Commanding is an input mechanism in Windows Presentation Foundation (WPF) which provides input handling at a more semantic level than device input. Examples of commands are the Copy, Cut, and Paste operations found on many applications.app
虽然英语捉鸡,可是不妨碍咱们阅读一手资料,燃鹅(●'◡'●),咱们看下Google的翻译:框架
指令是Windows Presentation Foundation(WPF)中的一种输入机制,它提供比设备输入更多语义级别的输入处理。命令的例子是在许多应用程序中找到的复制,剪切和粘贴操做。ide
好像也没什么用!仍是直接拿例子来看:函数
MainWindow.xaml
spa
<Window x:Class="UsingDelegateCommands.Views.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:prism="http://prismlibrary.com/" prism:ViewModelLocator.AutoWireViewModel="True" Title="Using DelegateCommand" Width="350" Height="275"> <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> <CheckBox IsChecked="{Binding IsEnabled}" Content="Can Execute Command" Margin="10"/> <Button Command="{Binding ExecuteDelegateCommand}" Content="DelegateCommand" Margin="10"/> <Button Command="{Binding DelegateCommandObservesProperty}" Content="DelegateCommand ObservesProperty" Margin="10"/> <Button Command="{Binding DelegateCommandObservesCanExecute}" Content="DelegateCommand ObservesCanExecute" Margin="10"/> <Button Command="{Binding ExecuteGenericDelegateCommand}" CommandParameter="Passed Parameter" Content="DelegateCommand Generic" Margin="10"/> <TextBlock Text="{Binding UpdateText}" Margin="10" FontSize="22"/> </StackPanel> </Window>
MainWindowViewModel.cs
翻译
using System; using Prism.Commands; using Prism.Mvvm; namespace UsingDelegateCommands.ViewModels { public class MainWindowViewModel : BindableBase { private bool _isEnabled; public bool IsEnabled { get { return _isEnabled; } set { SetProperty(ref _isEnabled, value); ExecuteDelegateCommand.RaiseCanExecuteChanged(); } } private string _updateText; public string UpdateText { get { return _updateText; } set { SetProperty(ref _updateText, value); } } public DelegateCommand ExecuteDelegateCommand { get; private set; } public DelegateCommand<string> ExecuteGenericDelegateCommand { get; private set; } public DelegateCommand DelegateCommandObservesProperty { get; private set; } public DelegateCommand DelegateCommandObservesCanExecute { get; private set; } public MainWindowViewModel() { ExecuteDelegateCommand = new DelegateCommand(Execute, CanExecute); DelegateCommandObservesProperty = new DelegateCommand(Execute, CanExecute) .ObservesProperty(() => IsEnabled); DelegateCommandObservesCanExecute = new DelegateCommand(Execute) .ObservesCanExecute(() => IsEnabled); ExecuteGenericDelegateCommand = new DelegateCommand<string>(ExecuteGeneric) .ObservesCanExecute(() => IsEnabled); } private void Execute() { UpdateText = $"Updated: {DateTime.Now}"; } private void ExecuteGeneric(string parameter) { UpdateText = parameter; } private bool CanExecute() { return IsEnabled; } } }
View部分:code
头部引入命名空间,指定ViewModeLocator模式:xml
xmlns:prism="http://prismlibrary.com/" prism:ViewModelLocator.AutoWireViewModel="True"
接着是一个:
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> </StackPanel>
接着内部是一组控件,一个CheckBox四个Button一个 TextBlock。
复选框的勾选状态绑定到一个布尔型属性上。
普通命令绑定
带参数的 命令绑定
为TextBlock的Text属性绑定数据源
Tips:
Binding语法 Property="{Binding PropertyPath}",PropertyPath就是VM
当为Command进行Binding的时候,还能够带参数,使用CommandParameter属性,上面的CommandParameter指定了一个字符串“Passed Parameter”,固然还能够为其Binding一个对象。
ViewModel部分:
set方法中的:
SetProperty(ref _isEnabled, value);
属性变动的通知,当视图状态更新后,会通知VM更改_isEnabled
。
ExecuteDelegateCommand.RaiseCanExecuteChanged();
这段代码,则会通知ExecuteDelegateCommand的可执行状态更改了,让他从新获取下可执行状态,那他是怎么获取可执行状态的呢?咱们看下这个Command:
ExecuteDelegateCommand = new DelegateCommand(Execute, CanExecute);
new 的时候,有两个参数,第一个是Action(无返回类型的方法)Execute(须要执行的方法),第二个是一个Func
private bool CanExecute() { return IsEnabled; }
很简单,直接返回了IsEnabled
,而他是跟视图的CheckBox的IsChecked绑定的,固然也能够返回_isEnabled
,而我更倾向后面这个,Public那个是给外人用的,蛤蛤。
固然可执行状态,还有其余的更优雅的写法,也就不用写ExecuteDelegateCommand.RaiseCanExecuteChanged();
了,具体代码以下:
DelegateCommandObservesProperty = new DelegateCommand(Execute, CanExecute) .ObservesProperty(() => IsEnabled); DelegateCommandObservesCanExecute = new DelegateCommand(Execute) .ObservesCanExecute(() => IsEnabled);
下面这个是带参数的命令(command),他的回调函数须要一个string类型的参数,在new的时候要指定入参类型:
ExecuteGenericDelegateCommand = new DelegateCommand<string>(ExecuteGeneric) .ObservesCanExecute(() => IsEnabled);
回调函数ExecuteGeneric:
private void ExecuteGeneric(string parameter) { UpdateText = parameter; }
总结:
ViewModel(简称VM,下文也偶尔会出现VM,也指ViewModel)的类须要继承BindableBase,BindableBase实现了INotifyPropertyChanged接口。
命令类型是DelegateCommand,这继承自DelegateCommandBase,而DelegateCommandBase实现了ICommand接口。
这俩接口是MVVM的底层接口。有兴趣的能够看一下 MVVMFoundation,他封装没有那么屡次,只有四个cs文件,能够直接看到,他是如何运用ICommand和INotifyPropertyChanged接口的。
有兴趣的能够看一下浅谈WPF中的MVVM框架--MVVMFoundation
可是,做为高级的咱们,就用高级的封装,有了火柴谁还燧木取火,233333
一般状况下,咱们的命令调用者直接调用咱们的命令,可是有些时候,咱们须要从外部(好比其余的视图或父视图)的控件调用该命令,那么就须要一个CompositeCommand。
CompositeCommand是一个由多个子命令组成的命令。它提供了执行子命令的全部关联方法(Execute和CanExecute)的功能,当全部子命令的可执行状态为True的时候CompositeCommand才能够被执行。