最近在项目中自己写了一个控件A,继承自contentcontrol,实现了icommandsource接口。(因需求特殊并没有使用buttonbase及它的派生类为基类),控件A在测试程序中运转良好,绑定的命令响应方法能够被正确执行。下边代码是控件A执行命令的部分:

  1. RoutedEventArgs rea = new RoutedEventArgs(Button.ClickEvent, this);
  2. RaiseEvent(rea);
  3.  
  4. if (!rea.Handled && Command != null)
  5. {
  6. Command.Execute(CommandParameter);
  7. }

  

但在实现项目中,我将控件A放在了另一个较为复制杂的控件B的template中,并在控件B的commandbindings中设置了命令绑定,命令使用的是WPF原生命令类型RoutedUICommand。这个时候诡异的事件发生了,不论我怎么在template里边设置控件A的commandtarget属性,上边代码执行了Command.Execute(CommandParameter)这句之后,B绑定的命令响应方法都不会被调用。

之后在群里问了一些大神,都没有得到解决方法,于是乎查了下.net码源,看看buttonbase是如何处理这个问题。

不看不知道,一看吓一跳,在buttonbase中处理命令时,用到了大量的.net项目里的internal类或方法(微软这是成心留一手啊!)

  1. #from buttonbase.cs
    /// <summary>
  2. /// This virtual method is called when button is clicked and it raises the Click event
  3. /// </summary>
  4. protected virtual void OnClick()
  5. {
  6. RoutedEventArgs newEvent = new RoutedEventArgs(ButtonBase.ClickEvent, this);
  7. RaiseEvent(newEvent);
  8.  
  9. MS.Internal.Commands.CommandHelpers.ExecuteCommandSource(this);
  10. }

  #from CommandHelpers.cs

  1. internal static void ExecuteCommandSource(ICommandSource commandSource)
  2. {
  3. CriticalExecuteCommandSource(commandSource, false);
  4. }
  5.  
  6. internal static void CriticalExecuteCommandSource(ICommandSource commandSource, bool userInitiated)
  7. {
  8. ICommand command = commandSource.Command;
  9. if (command != null)
  10. {
  11. object parameter = commandSource.CommandParameter;
  12. IInputElement target = commandSource.CommandTarget;
  13.  
  14. RoutedCommand routed = command as RoutedCommand;
  15. if (routed != null)
  16. {
  17. if (target == null)
  18. {
  19. target = commandSource as IInputElement;
  20. }
  21. if (routed.CanExecute(parameter, target))
  22. {
  23. routed.ExecuteCore(parameter, target, userInitiated);
  24. }
  25. }
  26. else if (command.CanExecute(parameter))
  27. {
  28. command.Execute(parameter);
  29. }
  30. }
  31. }

 从上边.net这几段代码里我们可以看到,buttonbase在执行命令里的时候,使用的是 CommandHelpers这个内部类中定义的方法,而这个方法的核心逻辑是先判断使用的命令是不是RoutedCommand类型,如果是的话则可能会使用RoutedCommand的内方法ExecuteCore去执行命令,而在这个方法中才有commandtarget这个参数。

总结一下,如果你的控件不是继承自buttonbase,那么就不能使用RoutedCommand.RoutedCommand这个内部方法,不能使用这个内部方法那么RoutedCommand就不会认你自己设置的commandtarget,那么如果.net库自己找到target不对,你再怎么设置也是徒劳。。。(我感觉被微软深深伤害了)

说明白点,不要把自己实现icommandsource的类型与routedcommand搭配使用!

WPF之坑——ICommandSource与RoutedUICommand的更多相关文章

  1. 我遇到的WPF的坑

    转自 林德熙Blog 本文:我遇到的WPF的坑 目录 单例应用在多实例用户无法使用 标记方法被使用 当鼠标滑过一个被禁用的元素时,让ToolTip 显示 获取设备屏幕数量 获取当前域用户 绑定资源文件 ...

  2. WPF之坑——surface触控失灵之谜

    本次又遇到了WPF编写触控程序的一个问题,虽然已解决,但原因确搞不太明白,希望有大神看到这篇文章帮我解答. 在项目中实现了自己定义的icommandsource,因为需要对触控有特殊需求,控件对鼠标与 ...

  3. WPF C# 命令的运行机制

    1.概述 1.1 WPF C# 命令的本质 命令是 WPF 中的输入机制,它提供的输入处理比设备输入具有更高的语义级别. 例如,在许多应用程序中都能找到的“复制”.“剪切”和“粘贴”操作就是命令. W ...

  4. wpf图片定点缩放

    去年犯小人,万事不顺,4月刚换工作,开始新工作 遇到一个小问题,需要读取图片,然后对图片进行定点缩放,很简答的逻辑,很简单的代码,但是,这尼玛我被wpf给坑了,这一坑就是三天 好了,很简单的一个UI ...

  5. 【Beta版本】冲刺-Day7

    队伍:606notconnected 会议时间:12月15日 目录 一.行与思 二.站立式会议图片 三.燃尽图 四.代码Check-in 一.行与思 张斯巍(433) 今日进展:修改界面,应用图标 明 ...

  6. 客户端浏览器- UWP兼容版本WebView

    WebView简介 在win10之前,浏览器控件有WPF版本webBrowser.Winform版本WebBrowser,浏览器内核为IE. win10之后,微软不再维护原有的WebBrowser,转 ...

  7. 2019-8-28-WPF-开发

    title author date CreateTime categories WPF 开发 lindexi 2019-8-28 11:3:39 +0800 2018-2-13 17:23:3 +08 ...

  8. 2019-10-16-WPF-控件-Content-的内容不显示下划线字符串

    title author date CreateTime categories WPF 控件 Content 的内容不显示下划线字符串 lindexi 2019-10-16 09:21:32 +080 ...

  9. dx wpf的各种坑

    这篇随笔总结dx wpf使用中的各种坑,持续更新~ LookUpEdit里内嵌的DXGrid的名字必须是"PART_GridControl",不能不写.也不能写错.我对比了2个小时 ...

随机推荐

  1. PAT L2-005 集合相似度(模拟集合set)

    给定两个整数集合,它们的相似度定义为:Nc/Nt*100%.其中Nc是两个集合都有的不相等整数的个数,Nt是两个集合一共有的不相等整数的个数.你的任务就是计算任意一对给定集合的相似度. 输入格式: 输 ...

  2. java的PDF纵横向打印

    PDF默认是纵向打印的,通过rotate()来让其改变为横向打印,一般在打印A4 12*21纸以及发票的时候会用横向打印.横向打印时页面会出现行转列以及列转行的情况,因此在设置页面大小的时候一定要宽度 ...

  3. spring boot2.03 spring cloud Finchley.RELEASE遇到的问题

    1.spring cloud bus 本地不能更新 原因是@RefreshScope注解要加在需要更新的controller上 2.No instances found of configserver ...

  4. 面向对象 Java练习

    package xin.bao; public class Pingguo { private String Zhonglei;// 种类 public String getZhonglei() { ...

  5. Codeforces 607A 动态规划

    A. Chain Reaction time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...

  6. 【Sikuli】Sikuli 文档

    http://sikulix-2014.readthedocs.io/en/latest/index.html

  7. hive的用户和用户权限

    HiverServer2支持远程多客户端的并发和认证,支持通过JDBC.Beeline等连接操作.hive默认的Derby数据库,由于是内嵌的文件数据库,只支持一个用户的操作访问,支持多用户需用mys ...

  8. gitlab VS github

    gitlab 和 github的比较 GitLab - 基于Git的项目管理软件 GitLab 是一个用于仓库管理系统的开源项目.使用Git作为代码管理工具,并在此基础上搭建起来的web服务.

  9. Python鸭子类型思想

    动态语言中经常提到鸭子类型,所谓鸭子类型就是:如果走起路来像鸭子,叫起来也像鸭子,那么它就是鸭子(If it walks like a duck and quacks like a duck, it ...

  10. 前端之css笔记1

    1  css引入方式 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...