博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
从PRISM开始学WPF(六)MVVM(二)Command?
阅读量:6089 次
发布时间:2019-06-20

本文共 4829 字,大约阅读时间需要 16 分钟。

原文:

命令绑定(Command)

什么是Command?

先看下微软官方的说明:

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.

虽然英语捉鸡,但是不妨碍我们阅读一手资料,燃鹅(●'◡'●),我们看下Google的翻译:

指令是Windows Presentation Foundation(WPF)中的一种输入机制,它提供比设备输入更多语义级别的输入处理。命令的例子是在许多应用程序中找到的复制剪切粘贴操作。

好像也没什么用!还是直接拿例子来看:

MainWindow.xaml

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
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
(ExecuteGeneric) .ObservesCanExecute(() => IsEnabled); } private void Execute() { UpdateText = $"Updated: {DateTime.Now}"; } private void ExecuteGeneric(string parameter) { UpdateText = parameter; } private bool CanExecute() { return IsEnabled; } }}

View部分:

头部引入命名空间,指定ViewModeLocator模式:

xmlns:prism="http://prismlibrary.com/"prism:ViewModelLocator.AutoWireViewModel="True"

接着是一个:

接着内部是一组控件,一个CheckBox四个Button一个 TextBlock。

  • CheckBox IsChecked="{Binding IsEnabled}"

复选框的勾选状态绑定到一个布尔型属性上。

  • Button Command="{Binding ExecuteDelegateCommand}"

普通命令绑定

  • Button Command="{Binding ExecuteGenericDelegateCommand}" CommandParameter="Passed Parameter"

带参数的 命令绑定

  • TextBlock Text="{Binding UpdateText}"

为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那个是给外人用的,蛤蛤。

当然可执行状态,还有其他的更优雅的写法:

DelegateCommandObservesProperty = new DelegateCommand(Execute, CanExecute)                .ObservesProperty(() => IsEnabled);            DelegateCommandObservesCanExecute = new DelegateCommand(Execute)                .ObservesCanExecute(() => IsEnabled);

下面这个是带参数的命令(command),他的回调函数需要一个string类型的参数,在new的时候要指定入参类型:

ExecuteGenericDelegateCommand = new DelegateCommand
(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接口的。

但是,作为高级的我们,就用高级的封装,有了火柴谁还燧木取火,233333

复合型命令绑定

通常情况下,我们的命令调用者直接调用我们的命令,但是有些时候,我们需要从外部(比如其他的视图或父视图)的控件调用该命令,那么就需要一个CompositeCommand

CompositeCommand是一个由多个子命令组成的命令。它提供了执行子命令的所有关联方法(ExecuteCanExecute)的功能,当所有子命令的可执行状态为True的时候CompositeCommand才可以被执行。

看下具体应用的代码:

声明:

public CompositeCommand SaveCommand { get; } = new CompositeCommand();

注册子命令:

SaveCommand.RegisterCommand(UpdateCommand);

取消注册:

SaveCommand.UnregisterCommand(UpdateCommand);

转载地址:http://yevwa.baihongyu.com/

你可能感兴趣的文章
Django为数据库的ORM写测试例(TestCase)
查看>>
web.xml中的contextConfigLocation在spring中的作用
查看>>
NYOJ-107 A Famous ICPC Team
查看>>
与众不同 windows phone (44) - 8.0 位置和地图
查看>>
Visual Studio Code 使用 ESLint 增强代码风格检查
查看>>
iOS设备中的推送(二):证书
查看>>
敏捷 - #3 原则:经常提供工作软件 ( #3 Agile - Principle)
查看>>
数据结构与算法:二分查找
查看>>
使用思科模拟器Packet Tracer与GNS3配置IPv6隧道
查看>>
iOS开发-NSPredicate
查看>>
我的友情链接
查看>>
Exchange Server 2003 SP2 数据存储大小限制修改
查看>>
expr命令用法-实例讲解
查看>>
酷派8705救砖
查看>>
iOS10里的通知与推送
查看>>
# C 语言编写二进制/十六进制编辑器
查看>>
EMS SQL Management Studio for MySQL
查看>>
我的友情链接
查看>>
做母亲不容易
查看>>
拷贝对象属性
查看>>