原文: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. March 28 2017 Week 13 Tuesday

    Never was anything great achieved without danger. 不经历风雨,又怎能见彩虹. After the rain, if there's the sunsh ...

  2. 页面三个txt加载联动省市县的代码,类似淘宝的收货地址的布局

    页面三个txt加载联动省市县的代码,假如有一个树形的JSON,分别显示的省市县这时候三个TXT怎么做联动效果呢,这里用framework7为例HTML: <div class="lis ...

  3. 【转】jQuery源码分析-03构造jQuery对象-源码结构和核心函数

    作者:nuysoft/高云 QQ:47214707 EMail:nuysoft@gmail.com 毕竟是边读边写,不对的地方请告诉我,多多交流共同进步.本章还未写完,完了会提交PDF. 前记: 想系 ...

  4. POJ 3020 Antenna Placement 【最小边覆盖】

    传送门:http://poj.org/problem?id=3020 Antenna Placement Time Limit: 1000MS   Memory Limit: 65536K Total ...

  5. POJ 3635 Full Tank? 【分层图/最短路dp】

    任意门:http://poj.org/problem?id=3635 Full Tank? Time Limit: 1000MS   Memory Limit: 65536K Total Submis ...

  6. 创建VS工程使用神经网络库——FANN

    编译: sourceforge上的FANN库带VS2010的工程,我机器上装的VS2005,用不了,愁人,只能手动创建工程了,编译不过,度娘不管用,FQ麻烦,用雅虎搜到一个工程的创建配置,调整配置试一 ...

  7. sql树形查询

    sql: 使用Common As:递归公用表 https://docs.microsoft.com/en-us/sql/t-sql/queries/with-common-table-expressi ...

  8. o'Reill的SVG精髓(第二版)学习笔记——第八章

    第八章:图案和渐变 要使用图案,首先要定义一个水平或者垂直方向重复的图形对象,然后用它填充另一个对象或者作为笔画使用.这个图形对象呗称作tile(瓷砖). 下面可以把SVG绘制的二次曲线作为图案. & ...

  9. 使用classList来实现两个按钮样式的切换

    classList属性的方法:add();remove();toggle(); 描述,在一些页面我们需要使用两个按钮来回切换,如图: 我们要使用到add()和remove()方法 html部分: &l ...

  10. yum仓库客户端搭建和NTP时间同步客户端配置

    一.yum仓库客户端搭建 yum源仓库搭建分为服务器端和客户端. 服务端主要提供软件(rpm包)和yumlist.也就是提供yum源的位置.一般是通过http或者ftp提供位置. 客户端的配置:yum ...