原文:WPF中的命令与命令绑定(一)

  WPF中的命令与命令绑定(一)
                                           周银辉

说到用户输入,可能我们更多地会联想到键盘、鼠标、手写笔,其实还用一种高级别的输入——命令(Commands),从WPF类库角度讲他们分别对于Keyboard,Mouse,Ink与ICommand。命令是一种语义级别的输入而不是设备级别的,比如“复制”与“粘贴”,但实现一个命令可以有很多中方式,比如“粘贴”,我们可以使用CTRL-V,也可以使用主菜单或右键菜单(上下文菜单)等等。在以往的.net版本中,要在软件界面上添加一个“粘贴”按钮,是非常麻烦的事情,你得监视剪切板中是否有可用的文本以及对应的文本框是否获得了焦点以便启用或禁用该按钮,当粘贴时你还得从剪切板中取得相应的文本并插入到文本框的合理位置,等等。

在WPF中提供的命令机制能非常简单地实现这些任务,下面的Demo演示了如何简单到不用手动编写一行后台逻辑代码便解决上面的难题的,你可以粘贴下面的代码到XamlPad:

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Name="Window"
    Title="Window1"
    Width="640" Height="480">

    <DockPanel LastChildFill="True">
        <Menu Width="Auto" Height="20" DockPanel.Dock="Top">
            <MenuItem Command="ApplicationCommands.Copy" Header="{Binding Path=Command.Text, RelativeSource={RelativeSource Self}}"/>
            <MenuItem Command="ApplicationCommands.Paste" Header="{Binding Path=Command.Text, RelativeSource={RelativeSource Self}}"/>
            <MenuItem Command="ApplicationCommands.Cut" Header="{Binding Path=Command.Text, RelativeSource={RelativeSource Self}}"/>
            <MenuItem Command="ApplicationCommands.Redo" Header="{Binding Path=Command.Text, RelativeSource={RelativeSource Self}}"/>
            <MenuItem Command="ApplicationCommands.Undo" Header="{Binding Path=Command.Text, RelativeSource={RelativeSource Self}}"/>
        </Menu>
        <RichTextBox>
            <FlowDocument>
                <Paragraph/>
            </FlowDocument>
        </RichTextBox>
    </DockPanel>
</Window>


Demo中菜单栏的菜单项不仅仅能完美地完成任务而且能根据文本框的状态和剪切板自动的启用与禁用,而我们却没有为这些复杂的逻辑编写任何的后台代码。这就是WPF中的命令机制为我们提供了方便。

注意这一行代码:

<MenuItem Command="ApplicationCommands.Copy" Header="{Binding Path=Command.Text, RelativeSource={RelativeSource Self}}"/>

我们将“复制”命令(ApplicationCommands.Copy)赋值给了菜单项的Command属性,实现了ICommandSource接口的元素都拥有该属性,这表示该元素可以作为一个“命令源”来引发某个命令,其Command属性就指示了其将引发的命令。

其实一个命令系统是被分为四个部分的:
Command(命令):一个语义级别的输入,比如“复制”,“左对齐”,“播放”等
CommandSource(命令源):引发某命令的元素,比如按钮,菜单项,键盘(Ctrl-C,F1等),鼠标等。
CommandTarget(命令目标):命令被作用的目标,比如文本框,播放器等。
CommandBinding(命令绑定):用于将命令和命令的处理逻辑链接起来,比如同样的"粘贴",但粘贴文本和粘贴图片的处理逻辑是不一样的,命令绑定负责将“粘贴”命令与合理的处理逻辑连接起来。
关于命令系统将在本文章的后续部分中讲解,不过值得一提的是,在上面的Demo中我们只指定了命令和命令源,并未指定命令目标,但它会以获取键盘焦点的元素(这里是我们的RichTextBox)作为默认值,而命令绑定以及命令的后台执行逻辑被隐藏到了RichTextBox内部,那些编写RichTextBox控件的开发人员会为我们编写该部分代码。

另外,你可能已经发现,在Demo中我们并没有为菜单项标题直接设置“复制”“粘贴”这样的文本,而是使用了如下的一个绑定:

Header="{Binding Path=Command.Text, RelativeSource={RelativeSource Self}}"/>

我们将菜单文本绑定到了命令的Text属性,这是因为,如果一个命令为RoutedUICommand类型,那么该命令将有一个Text属性来说明该命令对应到的文本名称,该Text属性会自动本地化的,也就是说如果你的计算机使用语言是简体中文的话该菜单项显示的是“复制”,如果你的计算机使用的语言是英语的话该菜单项显示的将是“Copy”。

WPF为我们提供了大量内置命令,包括ApplicationCommands,NavigationCommands,,MediaCommands,EditingCommands与ComponentCommands,以及控件开发人员为它们的控件也提供了很多特有的命令(比如Slider.DecreaseLarge 与 Slider.DecreaseSmall),这些足以应付平时的大多数应用,如果还不够的话,你可以为自己的应用自定义更多的命令。

在本随笔的后续部分我们将更加深入的探讨WPF的命令系统,敬请关注,谢谢。

WPF中的命令与命令绑定(一)的更多相关文章

  1. WPF中PasswordBox控件无法绑定Password属性解决办法

    在WPF中,默认的Password控件的Password属性是不允许为之绑定的,下面是一个解决绑定Password的方法的代码: 1.前台代码 <Window x:Class="Pas ...

  2. wpf中UserControl的几种绑定方式

    我们经常会抽取一些可重用的控件,某个属性是否需要重用,直接决定了这个属性的绑定方式. 1.完全不可重用的控件 有一些与业务强相关的控件,它们的属性完全来自ViewModel,越是相对复杂的控件,越容易 ...

  3. WPF中,多key值绑定问题,一个key绑定一个界面上的对象

    问题说明: 当用到dictionary<key,value>来储存数据的时候,有时候需要在界面上绑定一个key来显示value,这时候有两种思路: 一种是写一个自定义的扩展类,类似Bind ...

  4. WPF中的命令与命令绑定(二)

    原文:WPF中的命令与命令绑定(二) WPF中的命令与命令绑定(二)                                              周银辉在WPF中,命令(Commandi ...

  5. WPF学习笔记四之命令

    1.概念 对于程序来说,命令就是一个个任务,例如保存,复制,剪切这些操作都可以理解为一个个命令.即当我们点击一个复杂按钮时,此时就相当于发出了一个复制的命令,即告诉文本框执行一个复杂选中内容的操作,然 ...

  6. WPF中在MVVM模式下,后台绑定ListCollectionView事件触发问题

    问题:WPF中MVVM模式下 ListView绑定ListCollectionView时,CurrentChanged无法触发 解决方案: 初期方案:利用ListView的SelectionChang ...

  7. 在WPF中UserControl

    在这里我们将将打造一个UserControl(用户控件)来逐步讲解如何在WPF中自定义控件,并将WPF的一些新特性引入到自定义控件中来.我们制作了一个带语音报时功能的钟表控件, 效果如下: 在VS中右 ...

  8. 在WPF中自定义控件

    一, 不一定需要自定义控件在使用WPF以前,动辄使用自定义控件几乎成了惯性思维,比如需要一个带图片的按钮,但在WPF中此类任务却不需要如此大费周章,因为控件可以嵌套使用以及可以为控件外观打造一套新的样 ...

  9. 在WPF中自定义控件(2) UserControl

    原文:在WPF中自定义控件(2) UserControl 在WPF中自定义控件(2) UserControl                                               ...

  10. [转]在WPF中自定义控件 UserControl

    在这里我们将将打造一个UserControl(用户控件)来逐步讲解如何在WPF中自定义控件,并将WPF的一些新特性引入到自定义控件中来.我们制作了一个带语音报时功能的钟表控件, 效果如下: 在VS中右 ...

随机推荐

  1. myeclipse 阿里巴巴java开发规范

    今天发现阿里巴巴搞了个java开发规范,然后火了: 然后发现我也整了一下: 阿里巴巴java开发规范宣传页: http://mp.weixin.qq.com/s/IbibsXlWHlM59kfXJqR ...

  2. UVALive 6261 Jewel heist

    题意:珠宝大盗Arsen Lupin偷珠宝.在展厅内,每颗珠宝有个一个坐标为(xi,yi)和颜色ci. Arsen Lupin发明了一种设备,可以抓取平行x轴的一条线段下的所有珠宝而不触发警报, 唯一 ...

  3. Android(java)学习笔记46:反射机制

    1. 反射机制: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称 ...

  4. 基于Qt的相似QQ好友列表抽屉效果的实现

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/shuideyidi/article/details/30619167     前段时间在忙毕业设计, ...

  5. 【[SDOI2016]排列计数】

    一眼题,答案就是\(C_m^m*d_{n-m}\) 就是从\(n\)个中选取\(m\)个在位,剩下的错排,之后就是乘法原理了 但是我发现我的错排公式竟然一直不会推 这个递推式很简单,就是\(d[1]= ...

  6. 2018.12.25 Spring中JDBCTemplate模版API学习

    1 Spring整合JDBC模版 1.1 spring中土拱了一个可以操作数据库的对象.对象封装了jdbc技术 JDBCTemplateJDBC模板对象 1.2 与DBUtils中的QueryRunn ...

  7. HDFS副本存放读取

    HDFS作为Hadoop中 的一个分布式文件系统,而且是专门为它的MapReduce设计,所以HDFS除了必须满足自己作为分布式文件系统的高可靠性外,还必须为 MapReduce提供高效的读写性能,那 ...

  8. 工作流,WEB框架,UI组件网络收集整理

    工作流,WEB框架,UI组件网络收集整理 在博客园上逛了好多年,随手收录了一些工作流,WEB开发框架,UI组件,现在整理一下与大家分享. 由于个人能力与精力有限,望各位园友在评论中补充,我将全部整理到 ...

  9. JDBC配置文件db.properties(Mysql) 及dbutils的编写

    #数据库驱动driver=com.mysql.jdbc.Driver#数据库连接url=jdb:mysql://localhost:3306/newdb3?useUnicode=true&ch ...

  10. 【PBR的基本配置】

    PBR基于策略路由的配置 一:基于报文协议的本地PBR 1:首先进行理论分析:在SW1上利用基于报文报文协议类型的PBR,在sw1与sw3的连接链路上,利用acl制定允许tcp的报文通过3000,并与 ...