命令绑定(Command)

[7.1updated]这一节除了基础app部分,并没有什么变化

什么是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

<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部分:

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

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

接着是一个:

    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
</StackPanel>

接着内部是一组控件,一个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,就是一个返回布尔型的方法CanExecute来获取command的可执行状态,当上面通知他可执行状态变更后,他就会重新调用CanExecute方法来获取目前的可执行状态(也就是按钮的可按下状态),来看下这个方法:

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

从PRISM开始学WPF(六)MVVM(二)Command-更新至Prism7.1的更多相关文章

  1. 从PRISM开始学WPF(一)WPF-更新至Prism7.1

    原文:从PRISM开始学WPF(一)WPF-更新至Prism7.1 我最近打算学习WPF ,在寻找MVVM框架的时候发现了PRISM,在此之前还从一些博客上了解了其他的MVVM框架,比如浅谈WPF中的 ...

  2. 从PRISM开始学WPF(三)Prism-Region-更新至Prism7.1

    [7.1update]在开始前,我们先看下版本7.1中在本实例中的改动. 首先,项目文件中没有了Bootstrapper.cs,在上一篇的末尾,我们说过了,在7.1中,不见推荐使用Bootstrapp ...

  3. 从PRISM开始学WPF(四)Prism-Module-更新至Prism7.1

    0x4Modules Modules是能够独立开发.测试.部署的功能单元,Modules可以被设计成实现特定业务逻辑的模块(如Profile Management),也可以被设计成实现通用基础设施或服 ...

  4. 从PRISM开始学WPF,Prism7更新了什么

    当时我在搬运Prism6.3的sample代码的时候,就是因为网上的资料太老旧,万万没想到这给自己挖了一个坑,因为我在做笔记的时候,prism已经在更新7.0了 现在已经是7.2了,(lll¬ω¬), ...

  5. 从PRISM开始学WPF(七)MVVM(三)事件聚合器EventAggregator?

    原文:从PRISM开始学WPF(七)MVVM(三)事件聚合器EventAggregator? 从PRISM开始学WPF(一)WPF? 从PRISM开始学WPF(二)Prism? 从PRISM开始学WP ...

  6. 从PRISM开始学WPF(七)MVVM(三)事件聚合器EventAggregator-更新至Prism7.1

    原文:从PRISM开始学WPF(七)MVVM(三)事件聚合器EventAggregator-更新至Prism7.1 事件聚合器EventAggregator [7.1updated]除了app部分,没 ...

  7. 从PRISM开始学WPF(一)WPF?

    从PRISM开始学WPF(一)WPF?   我最近打算学习WPF ,在寻找MVVM框架的时候发现了PRISM,在此之前还从一些博客上了解了其他的MVVM框架,比如浅谈WPF中的MVVM框架--MVVM ...

  8. 从PRISM开始学WPF(八)导航Navigation-更新至Prism7.1

    原文:从PRISM开始学WPF(八)导航Navigation-更新至Prism7.1 0x6Navigation [7.1updated] Navigation 在wpf中并没有变化 Basic Na ...

  9. 从PRISM开始学WPF(番外)共享上下文 RegionContext?

    原文:从PRISM开始学WPF(番外)共享上下文 RegionContext? RegionContext共享上下文 There are a lot of scenarios where you mi ...

  10. 从PRISM开始学WPF(八)导航Navigation?

    原文:从PRISM开始学WPF(八)导航Navigation? 0x6Navigation Basic Navigation Prism中的Navigation提供了一种类似导航的功能,他可以根据用户 ...

随机推荐

  1. BZOJ_1697_[Usaco2007 Feb]Cow Sorting牛排序_贪心

    BZOJ_1697_[Usaco2007 Feb]Cow Sorting牛排序_贪心 Description 农夫JOHN准备把他的 N(1 <= N <= 10,000)头牛排队以便于行 ...

  2. ts基础(1)

    // let num:number = 12; // let boo:boolean = true; // let str:string = "adfd"; // str = 'a ...

  3. input表单中嵌入百度地图

    在做项目开发中,常常会用到定位的操作,比如在做一些资产房产等方面的业务的时候,需要知道资产的具体位置,并将位置信息保存下来,这个时候我们可以使用form表单嵌入百度地图的方式来实现这个功能,下面请看详 ...

  4. 【Canal源码分析】Sink及Store工作过程

    一.序列图 二.源码分析 2.1 Sink Sink阶段所做的事情,就是根据一定的规则,对binlog数据进行一定的过滤.我们之前跟踪过parser过程的代码,发现在parser完成后,会把数据放到一 ...

  5. HTTP协议中GET和POST区别

    GET一般用于获取和查询资源信息:POST一般用于更新信息,表示可能修改服务器上资源的请求 GET请求一般是幂等的 GET请求数据会附加在url之后,POST请求数据放到request-body中 G ...

  6. 记一次重大生产事故,在那 0.1s 我想辞职不干了!

    一.发生了什么? 1.那是一个阳光明媚的下午,老婆和她的闺蜜正在美丽的湖边公园闲逛(我是拎包拍照的). 2.突然接到甲方运营小妹的微信:有个顾客线上付款了,但是没有到账,后台卡在微信支付成功(正常状态 ...

  7. dev和master合并冲突解决

    前景 master主分支,dev是开发分支,master会保持最新的dev代码 问题的产生 dev开发新功能 版本发布,dev合并到了master,发布生产环境 新需求来了,在dev进行开发 同时,线 ...

  8. Asp.Net Core&Docker部署到树莓派3B中

    花了一点时间将吃灰数月的树莓派装上了Docker,并在容器中部署了一个Asp.Net Core应用程序,通过花生壳映射树莓派中的程序,可以使用外网访问树莓派,玩起来很有意思(外网访问地址:http:/ ...

  9. 第4章 令牌端点(Token Endpoint) - IdentityModel 中文文档(v1.0.0)

    令牌端点的客户端库(OAuth 2.0和OpenID Connect)作为HttpClient一组扩展方法提供.这允许HttpClient以您喜欢的方式创建和管理生命周期- 例如静态或通过像Micro ...

  10. 第65章 博客帖子 - Identity Server 4 中文文档(v1.0.0)

    第65章 博客帖子 65.1 团队帖子 65.1.1 2019 IdentityServer中的范围和声明设计 尝试使用IdentityServer4的设备流程 OAuth2中隐含流的状态 另一种保护 ...