首页 > 其他分享 >WPF命令(Command)

WPF命令(Command)

时间:2023-05-29 21:23:28浏览次数:49  
标签:CanExecute 接口 命令 Command 事件 WPF

本篇文章学习于: 刘铁猛老师《深入浅出WPF》

命令是什么?

你可能会问:“有了路由事件为什么还需要命令系统呢?”事件的作用是发布、传播一些消息,消息送达接收者,事件的使命也就完成了,至于如何响应事件送来的消息事件并不做规定,每个接收者可以使用自己的行为来响应事件。也就是说,事件不具有约束力。命令与事件的区别就在于命令是具有约束力的。
的确,实际编程工作中就算只使用事件、不使用命令,程序的逻辑也一样可以被驱动得很好,但我们不能阻止程序员按自己的习惯去编写代码。比如保存事件的处理器,程序员们可以写Save()/SaveHandler()/SaveDocument(),这些都符合代码规范,但迟早有一天整个项目会变得无法被读懂,新来的程序员或修改 bug 的程序员会很抓狂。
如果使用命令,情况会好很多—当Save命令到达某个组件时,命令会主动去调用组件的Save()方法,而这个方法可能被定义在基类或者接口里(即保证了这个方法一定是存在的),这就在代码结构和命名上做了约束。不但如此,命令还可控制接收者“先做校验、再保存、然后关闭”,也就是说,命令除了可以约束代码,还可以约束步骤逻辑,这让新来的程序员想犯错都难,也让修改bug 的程序员很快能找到规律、容易上手。

命令系统的基本元素和关系

WPF的命令系统由几个基本要素构成,它们是:

  • 命令(Command):WPF 的命令实际上就是实现了ICommand 接口的类,平时使用最多的是RoutedCommand类。我们还会学习使用自定义命令。
  • 命令源(Command Source):即命令的发送者,是实现了ICommandSource接口的类。很多界面元素都实现了这个接口,其中包括 Button、Menultem、ListBoxltem等。
  • 命令目标(Command Target):即命令将发送给谁,或者说命令将作用在谁身上。命令目标必须是实现了IInputElement接口的类。
  • 命令关联(Command Binding):负责把一些外围逻辑与命令关联起来,比如执行之前对命令是否可以执行进行判断、命令执行之后还有哪些后续工作等。

image.png

小试命令——使用 RoutedCommand

<Window x:Class="Demo5.Wpf命令.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:Demo5.Wpf命令"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <StackPanel x:Name="stackPanel">
        <TextBox x:Name="tbTest" Background="AliceBlue" FontSize="50"/>
        <Button x:Name="btnCommand" Content="发送命令"/>
    </StackPanel>
</Window>

image.png
image.png

namespace Demo5.Wpf命令 {
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window {
        public MainWindow() {
            InitializeComponent();

            InitCommand();
        }

        // 声明并定义命令
        private RoutedCommand clrCmd = new RoutedCommand("Clear", typeof(Window));

        private void InitCommand() {
            // 把命令赋值给命令源,并指定快捷键 “Alt+C”
            this.btnCommand.Command = clrCmd;
            this.clrCmd.InputGestures.Add(new KeyGesture(Key.C, ModifierKeys.Alt));

            // 指定命令目标
            this.btnCommand.CommandTarget = this.tbTest;

            // 创建命令关联
            CommandBinding cb=new CommandBinding();
            cb.Command = this.clrCmd;// 只关注与clrCmd相关的事件
            cb.CanExecute += Cb_CanExecute;
            cb.Executed += Cb_Executed;

            // 把命令关联安置在外围控件上
            this.stackPanel.CommandBindings.Add(cb);
        }

        // 当探测 命令是否可以执行时,此方法被调用
        private void Cb_CanExecute(object sender, CanExecuteRoutedEventArgs e) {
            if(string.IsNullOrEmpty(this.tbTest.Text)) {
                e.CanExecute = false;
            } else {
                e.CanExecute= true;
            }
            e.Handled = true;// 避免继续向上传而降低程序性能
        }

        // 当命令送达目标后,此方法被调用
        private void Cb_Executed(object sender, ExecutedRoutedEventArgs e) {
            this.tbTest.Clear();

            e.Handled = true;
        }
    }
}

命令库和命令参数

微软在WPF类库里准备了一些便捷的命令库,这些命令库包括:

  • ApplicationCommands
  • ComponentCommands
  • NavigationCommands
  • MediaCommands
  • EditingCommands

它们都是静态类,而命令就是用这些类的静态只读属性以单件模式暴露出来的。

前面提到命令库里有很多WPF 预制的命令,如 New、Open、Copy、Cut、Paste等。这些命令都是ApplicationCommands类的静态属性,所以它们的实例永远只有一个,
这就引出一个问题:如果界面上有两个按钮,一个用来新建Teacher 的档案,另一个用来新建Student 的档案,都使用New命令的话,程序应该如何区别新建的是什么档案呢?
答案是使用CommandPrameter。

近观命令

WPF的命令是实现了ICommand 接口的类。ICommand 接口非常简单,只包含两个方法和一个事件:

  • Execute方法:命令执行,或者说命令作用于命令目标之上。需要注意的是,现实世界中的命令是不会自己“执行”的,它只能“被执行”,而在这里,执行变成了命令的方法,颇有点儿拟人化的味道。
  • CanExecute方法:在执行之前用来探知命令是否可被执行。
  • CanExecuteChanged事件:当命令可执行状态发生改变时,可激发此事件来通知其他对象。

RoutedCommand 就是这样一个实现了ICommand接口的类。RoutedCommand在实现ICommand接口时,并未向Execute和 CanExecute方法中添加任何逻辑,也就是说,它是通用的、与具体业务逻辑无关的。

标签:CanExecute,接口,命令,Command,事件,WPF
From: https://www.cnblogs.com/swbna/p/17441691.html

相关文章

  • Wpf基础入门——XAML篇
    本篇文章学习于:刘铁猛老师《深入浅出WPF》什么是“项目模板”?最简单的WPF程序App.xamlMainWindow.xamlMainWindows.cs浅析用户界面的树型结构示例:在XAML中为对象属性赋值Attribute=Value形式例如:【不能设置太复杂的值】可以注意到在xaml文件中设置的value都是str......
  • Wpf基础入门——绑定(Binding)
    本篇文章学习于:刘铁猛老师《深入浅出WPF》Bing基础Binding更注重表达它是一种像桥梁一样的关联关系。WPF中,正是在这段桥梁上我们有机会为往来流通的数据做很多事情。如果把Binding比作数据的桥梁,那么它的两端分别是Binding的源(Source)和目标(Target)。一般情况下,Binding源是......
  • Wpf基础入门——资源(Resources)
    本篇文章学习于:刘铁猛老师《深入浅出WPF》WPF对象级资源每个WPF的界面元素都具有一个名为Resources的属性,这个属性继承自FrameworKElement类,其类型为ResourceDictionary。ResourceDictionary能够以“键一值”对的形式存储资源,当需要使用某个资源时,使用“键一值”对可以索引......
  • 001_常见的DOS命令
    常见的DOS命令#查看目录下的全部文件dir#切换目录cd#返回上级cd..#清理屏幕cls#查看电脑ipipconfig#打开应用 计算器calc 图画mspaint 记事本notepad#ping命令ping#文件操作 md目录名(创建文件夹) rd目录名(移除文件夹) cd>文件名(进入文件) del文件名(删除文件......
  • WPF概述
    文章来源:WindowsPresentationFoundation-WPF.NETFrameworkWPF概述WindowsPresentationFoundation(WPF)可以创建适用于Windows且具有非凡视觉效果的桌面客户端应用程序。WPF的核心是一个与分辨率无关且基于矢量的呈现引擎,旨在充分利用现代图形硬件。WPF通过一......
  • 1.docker简介与常用命令
    1.简介1.1.介绍Docker是基于Go语言实现的云开源项目。Docker的主要目标是Build,ShipandRunAnyApp,Anywhere,也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的APP(可以是一个WEB应用或数据库应用等等)及其运行环境能够做到“一次镜像,处处运行”。Docker......
  • Wpf基础入门——控件介绍
    本篇文章学习于:刘铁猛老师《深入浅出WPF》控件到底是什么?WPF中是数据驱动UI,数据是核心、是主动的;UI从属于数据并表达数据、是被动的。Control是数据和行为的载体,而无需具有固定的形象。控件的派生关系如下:WPF的内容模型各类内容模型详解我们把符合某类内容模型的UI元......
  • evo测试命令
    cd/home/slam/catkin_ws/src/ORB_SLAM2双目:cd/home/slam/catkin_ws/src/ORB_SLAM2./Examples/Stereo/stereo_eurocVocabulary/ORBvoc.txtExamples/Stereo/EuRoC.yaml/home/slam/datasets/V1_01_easy/mav0/cam0/data/home/slam/datasets/V1_01_easy/mav0/cam1/dataExampl......
  • web基础漏洞-系统命令注入
    1、介绍应用程序有时需要调用一些执行系统命令的函数,如在php中,使用system、exec、shell_exec、passthru、popen、proc_popen等函数可以执行系统命令。当黑客能控制这些函数中的参数时,就可以将恶意的系统命令拼接到正常命令中,从而造成命令执行攻击。2、windows支持的管道符|直......
  • Linux常见命令汇总
    Linux常用命令1、Linux系统简介开源免费使用,技术支持:主要是字符模式,命令行界面操作,更加稳定。2、为啥学?负责搭建和维护,后端服务器搭建硬件服务器云服务器远程链接的工具Xshell3、xshell链接4、Linux目录结构层级式的树状目录结构"/"根目录"~"表示当前目录的加目录,超......