[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才能夠被執行。