WPF_09_绑定

发布时间:2022-06-30 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了WPF_09_绑定脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

使用路由事件可相应广泛的鼠标和键盘动作,但事件是非常低级的元素。在实际应用过程中,功能被划分成一些高级的任务,可通过不同的动作和用户界面元素触发,包括主菜单、上下文菜单、键盘以及工具栏。定义这些任务-命令-并将控件连接到命令,从而不需要重复编写事件处理代码。更重要的,当命令不可用时,命令特性通过自动禁用控件来管理用户界面的状态。

命令模型

WPF命令模型由许多可变的部分组成:

  • 命令 : 命令表示程序任务,并跟踪任务是否能够被执行。然而命令不包含执行程序任务的代码。
  • 命令绑定 : 每个命令绑定针对界面的具体区域,单个命令可用于多个地方。
  • 命令源 : 命令源触发命令。
  • 命令目标 : 命令目标是在其中执行命令的元素。

ICommand 接口

命令模型的核心是 System.Windows.Input.ICommand 接口,包含两个方法和一个事件:

public interface ICommand
{
    // 程序任务逻辑
    void Execute(object parameter);
    // 返回命令的状态-true代表可用,false代表不可用
    bool CanExecute(object parameter);

    // 指示信号,状态改变
    event EventHandler CanExecuteChanged;
}

RoutedCommand 类

自己创建命令时,不会直接实现 ICommand 接口,而是继承 System.Windows.Input.RoutedCommand 类。如果是实现 ICommand 接口,代码被硬连接到命令,没有事件冒泡。RoutedCommand 类不包含任何程序逻辑,只代表命令,这意味着各个RoutedCommand 对象具有相同的功能。RoutedCommand为事件冒泡和隧道添加一些额外的基础结构,使得命令在WPF元素层次结构中冒泡

WPF命令为什么需要路由事件? WPF使用了大量预先构建的命令,不包含实际代码,为确保可在某个位置处理事件,甚至事件是由同一个窗口中不同命令源引发的,就需要使用事件冒泡的功能。 为什么非要使用预先构建的命令? 预先构建命令为集成提供了更好的可能,是WPF可插入体系架构的主要部分之一。

RoutedUICommand 类

在程序中处理的大部分命令不是 RoutedCommand 对象,而是 RoutedUICommand 类的实例。实际上,WPF提供的所有预先构建好的命令都是 RoutedUICommand对象

RoutedUICommand 用于具有文本的命令,这些文本显示在界面某些地方(菜单项文本,工具按钮的提示)。Text属性是为了命令显示的文本,这样可以在某个位置执行本地化。如果命令文本不会在界面上显示,RoutedUICommand和RoutedCommand是等效的。

命令库

WPF提供了基本命令库,通过 5 个专门的静态类的静态属性提供:

  • ApplicationCommands : 通用命令,包括剪切板命令(Copy,Cut,Paste)和文档命令(New,Open,Save,Save as,Print).
  • NavigationCommands : 用于导航的命令。(BrowseBack,BrowseForward,NextPage,IncreaseZoom,Refresh).
  • EditingCommands : 文档编辑命令。(MoveToLinedEnd,MoveLeftByWord,MoveUpByPage,SelectToLinedEnd,SelectLeftByWord,ToggleBold,ToggleUnderline)
  • ComponentCommands : 用户界面组件使用的命令。
  • MediaCommands : 多媒体命令。(Play,Pause,NextTrack,IncreaseVolume).

许多命令对象都有一个额外的特征:默认输入绑定 ,例如 ApplicationCommands.Open 命令被映射到 Ctrl+O 快捷键。

执行命令

命令绑定将执行转发给普通的事件处理程序。

命令源

触发命令库的方法是将它们关联到实现了 ICommandSource 接口的控件,包括 ButtonBase类控件(Button,CheckBox等),ListBoxItem,Hyperlink,MenuItem. ICommandSource 接口定义了三个属性:

名称 说明
Command 指向连接的命令,必填
CommandParameter 希望命令发送的数据
CommandTarget 将在其中执行命令的元素
<Button Command="ApplicationCommands.New">New</Button>

<!--WPF很智能,能自己查找5个命令容器类-->
<Button Command="New">New</Button>
<!--但上面这种语法不够明确,不够清晰-->

命令绑定

为命令创建绑定需要明确三件事情:

  • 当触发时执行什么操作
  • 如何确定命令是否能够被执行
  • 命令在何处起作用
// 创建绑定
CommandBinding binding = new CommandBinding(ApplicationCommands.New);
// 绑定执行委托
binding.Executed += NewCommand_Executed;
// 注册绑定,通过事件冒泡进行工作
this.CommandBindings.Add(Binding);

上面代码里的绑定被添加到窗口的 CommandBindings 集合中,这通过事件冒泡进行工作,当单击按钮时 CommandBinding.Executed 事件从按钮冒泡到窗口。CommandBindings 属性是在 UIElement 基类中定义的,也可以将绑定直接添加到按钮中。为了灵活性,绑定通常添加到顶级窗口。如果希望在多个窗口使用相同的命令,需要在这些窗口中分别创建命令绑定。

使用XAML声明方式关联命令:

<Window >
    <Window.CommandBindings>
        <CommandBinding Command="ApplicationCommands.New"
            Executed="NewCommand_Executed"/>
    </Window.CommandBindings>

    <Button Command="ApplicationCommands.New">New</Button>
</Window>

多命令源

如果此时同一窗体的菜单也使用New命令:

<Menu>
    <MenuItem Header="File">
        <MenuItem Command="New"></MenuItem>
    </MenuItem>
</Menu>

这里,New菜单并没有设置 Header 属性,因为MenuItem很智能,可以从命令中提取文本(Button不具有这一特性)。在不同语言本地化应用程序时很重要。MenuItem还能自动提取 Command.InputBindings 集合中的第一个快捷键。

微调命令文本

其他 ICommandSource 不会自动提取命令项文本,但通过一点额外的工作也能实现这个功能。

一种是直接从静态命令对象中提取文本:

<!--获取命令名,并作为按钮的文本-->
<Button Command="New" Content="{x:Static ApplicationCommands.New}"/>

这种方法只是调用命令对象的 ToString() 方法,得到的是命令名,而不是命令的文本(多个单词间有空格)。

另一个更好的方法是使用数据绑定表达式,绑定到当前元素。

<Button Margin="5" Command="New"
    Content="{Binding RelativeSource={RelativeSource Self}, Path=Command.Text}">
</Button>

直接调用命令

并非只能实现 ICommandSource 接口的类能触发命令,也可以用 Execute() 方法直接调用来自任何事件处理程序的方法。

ApplicationCommands.New.Execute(null, targetElement);

目标元素是WPF开始查找命令绑定的地方,可使用包含窗口(具有命令绑定)或嵌套的元素。也可以在关联的 CommandBinding 对象中调用 Execute() 方法,这种情况不需要提供目标元素。

this.CommandBindings[0].Command.Execute(null);

高级命令

自定义命令通过实例化一个新的 RoutedUICommand 对象:

public class DataCommands
{
    private static RoutedUICommand requery;

    static DataCommands()
    {
        InputGestureCollection inputs = new InputGestureCollection();
        inputs.Add(new KeyGesture(Key.R, ModifierKeys.Control, "Ctrl+R"));

        requery = new RoutedUICommand("Requery", "Requery", typeof(DataCommands), inputs);
    }

    public static RoutedUICommand Requery
    {
        get {return requery;}
    }
}
<Button Command="local:DataCommands.Requery"
    Executed="RequeryCommand_Executed">Requery</Button>

使用命令参数

通过设置 CommandParameter 属性可以传递额外信息:

<Button Command="NavigationCommands.Zoom"
    CommandParameter="{Binding ElementName=txtZoom, Path=Text}">Zoom To Value
</Button>

我的公众号

WPF_09_绑定

脚本宝典总结

以上是脚本宝典为你收集整理的WPF_09_绑定全部内容,希望文章能够帮你解决WPF_09_绑定所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签: