即使设置了 CommandParameter,ICommand.CanExecute 也会传递 null

2024-01-13

我有一个棘手的问题,我正在绑定ContextMenu到一组ICommand-派生对象,并设置Command and CommandParameter每个属性MenuItem通过样式:

<ContextMenu
    ItemsSource="{Binding Source={x:Static OrangeNote:Note.MultiCommands}}">
    <ContextMenu.Resources>
        <Style
            TargetType="MenuItem">
            <Setter
                Property="Header"
                Value="{Binding Path=Title}" />
            <Setter
                Property="Command"
                Value="{Binding}" />
            <Setter
                Property="CommandParameter"
                Value="{Binding Source={x:Static OrangeNote:App.Screen}, Path=SelectedNotes}" />
...

然而,虽然ICommand.Execute( object )按其应有的方式传递一组选定的音符,ICommand.CanExecute( object )(创建菜单时调用)传递 null。我已经检查过,所选笔记集合在调用之前已正确实例化(事实上,它在其声明中分配了一个值,因此它永远不会null)。我不明白为什么 CanEvaluate 会通过null.


我已确定 ContextMenu 中至少存在两个错误,导致其 CanExecute 调用在不同情况下不可靠。当命令设置后,它立即调用 CanExecute。以后的调用是不可预测的,而且肯定不可靠。

我花了一整夜的时间试图找出它会失败的精确条件并寻找解决方法。最后我放弃并切换到触发所需命令的 Click 处理程序。

我确实确定我的问题之一是更改 ContextMenu 的 DataContext 可能会导致在绑定新 Command 或 CommandParameter 之前调用 CanExecute。

据我所知,解决此问题的最佳解决方案是使用您自己的 Command 和 CommandBinding 附加属性,而不是使用内置属性:

  • 设置附加的 Command 属性后,订阅 MenuItem 上的 Click 和 DataContextChanged 事件,并订阅 CommandManager.RequerySuggested。

  • 当 DataContext 更改、RequerySuggested 出现或两个附加属性之一更改时,使用 Dispatcher.BeginInvoke 安排调度程序操作,该操作将调用 CanExecute() 并更新 MenuItem 上的 IsEnabled。

  • 当 Click 事件触发时,执行 CanExecute 操作,如果通过,则调用 Execute()。

用法与常规 Command 和 CommandParameter 类似,但使用附加属性:

<Setter Property="my:ContexrMenuFixer.Command" Value="{Binding}" />
<Setter Property="my:ContextMenuFixer.CommandParameter" Value="{Binding Source=... }" />

该解决方案有效并绕过了 ContextMenu 的 CanExecute 处理中的错误的所有问题。

希望有一天 Microsoft 能够解决 ContextMenu 的问题,并且不再需要此解决方法。我这里有一个复制案例,我打算将其提交给 Connect。也许我应该行动起来并真正做到这一点。

什么是 RequerySuggested,为什么使用它?

RequerySuggested 机制是 RoutedCommand 有效处理 ICommand.CanExecuteChanged 的​​方法。在非 RoutedCommand 世界中,每个 ICommand 都有自己的 CanExecuteChanged 订阅者列表,但对于 RoutedCommand,任何订阅 ICommand.CanExecuteChanged 的​​客户端实际上都会订阅 CommandManager.RequerySuggested。这个更简单的模型意味着任何时候 RoutedCommand 的 CanExecute 可能发生更改,所需要做的就是调用 CommandManager.InvalidateRequerySuggested(),这将执行与触发 ICommand.CanExecuteChanged 相同的操作,但同时在后台线程上对所有 RoutedCommand 执行此操作。此外,RequerySuggested 调用被组合在一起,以便如果发生许多更改,则只需调用 CanExecute 一次。

我建议您订阅 CommandManager.RequerySuggested 而不是 ICommand.CanExecuteChanged 的​​原因是: 1. 您不需要代码来删除旧订阅并在每次 Command 附加属性的值发生变化时添加新订阅,2. CommandManager.RequerySuggested 具有内置的弱引用功能,允许您设置事件处理程序并仍然被垃圾收集。对 ICommand 执行相同操作需要您实现自己的弱引用机制。

另一方面,如果您订阅 CommandManager.RequerySuggested 而不是 ICommand.CanExecuteChanged,您将只能获得 RoutedCommands 的更新。我专门使用 RoutedCommands,因此这对我来说不是问题,但我应该提到,如果您有时使用常规 ICommand,则应该考虑执行弱订阅 ICommand.CanExecutedChanged 的​​额外工作。请注意,如果您执行此操作,则无需订阅 RequerySuggested,因为 RoutedCommand.add_CanExecutedChanged 已为您执行此操作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

即使设置了 CommandParameter,ICommand.CanExecute 也会传递 null 的相关文章

  • 适合初学者的良好调试器教程[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 有谁知道一个好的初学者教程 在 C 中使用调试器 我感觉自己好像错过了很多 我知道怎么做 单步执行代码并查看局部变量 虽然这常常给我带来问
  • 代码 GetAsyncKeyState(VK_SHIFT) & 0x8000 中的这些数字是什么?它们是必不可少的吗?

    我试图在按下按键的简单动作中找到这些数字及其含义的任何逻辑解释 GetAsyncKeyState VK SHIFT 0x8000 可以使用哪些其他值来代替0x8000它们与按键有什么关系 GetAsyncKeyState 根据文档返回 如果
  • 查找进程的完整路径

    我已经编写了 C 控制台应用程序 当我启动应用程序时 不使用cmd 我可以看到它列在任务管理器的进程列表中 现在我需要编写另一个应用程序 在其中我需要查找以前的应用程序是否正在运行 我知道应用程序名称和路径 所以我已将管理对象搜索器查询写入
  • JNI 将 Char* 2D 数组传递给 JAVA 代码

    我想从 C 代码通过 JNI 层传递以下指针数组 char result MAXTEST MAXRESPONSE 12 12 8 3 29 70 5 2 42 42 在java代码中我写了以下声明 public static native
  • 当一组凭据下的计划任务启动的进程在另一组凭据下运行另一个程序时,Windows 是否有限制

    所以我有一个简单的例子 其中我有应用程序 A 它对用户 X 本地管理员 有一些硬编码的凭据 然后它使用硬编码的绝对路径启动带有这些凭据的应用程序 B A 和 B 以及 dotnet 控制台应用程序 但是它们不与控制台交互 只是将信息写入文件
  • 查看 NuGet 包依赖关系层次结构

    有没有一种方法 文本或图形 来查看 NuGet 包之间的依赖关系层次结构 如果您使用的是新的 csproj 您可以在此处获取所有依赖项 在项目构建后 项目目录 obj project assets json
  • 从客户端访问 DomainService 中的自定义对象

    我正在使用域服务从 Silverlight 客户端的数据库中获取数据 在DomainService1 cs中 我添加了以下内容 EnableClientAccess public class Product public int produ
  • File.AppendText 尝试写入错误的位置

    我有一个 C 控制台应用程序 它作为 Windows 任务计划程序中的计划任务运行 此控制台应用程序写入日志文件 该日志文件在调试模式下运行时会创建并写入应用程序文件夹本身内的文件 但是 当它在任务计划程序中运行时 它会抛出一个错误 指出访
  • 在Linux中,找不到框架“.NETFramework,Version=v4.5”的参考程序集

    我已经设置了 Visual studio 来在我的 Ubuntu 机器上编译 C 代码 我将工作区 我的代码加载到 VS 我可以看到以下错误 The reference assemblies for framework NETFramewo
  • 类型约束

    我有以下类层次结构 class Header IEnumerable
  • 为什么从字典中获取时会得到 Action<> 的克隆?

    我有以下字典 private Dictionary
  • 在视口中查找 WPF 控件

    Updated 这可能是一个简单或复杂的问题 但在 wpf 中 我有一个列表框 我用一个填充数据模板从列表中 有没有办法找出特定的数据模板项位于视口中 即我已滚动到其位置并且可以查看 目前我连接到了 listbox ScrollChange
  • 在 NaN 情况下 to_string() 可以返回什么

    我使用 VS 2012 遇到了非常令人恼火的行为 有时我的浮点数是 NaN auto dbgHelp std to string myFloat dbgHelp最终包含5008角色 你不能发明这个东西 其中大部分为0 最终结果是 0 INF
  • 使 Guid 属性成为线程安全的

    我的一个类有一个 Guid 类型的属性 该属性可以由多个线程同时读写 我的印象是对 Guid 的读取和写入不是原子的 因此我应该锁定它们 我选择这样做 public Guid TestKey get lock testKeyLock ret
  • Unity:通过拦截将两个接口注册为一个单例

    我有一个实现两个接口的类 我想对该类的方法应用拦截 我正在遵循中的建议Unity 将两个接口注册为一个单例 https stackoverflow com questions 1394650 unity register two inter
  • WebBrowser.Print() 等待完成。 。网

    我在 VB NET 中使用 WebBrowser 控件并调用 Print 方法 我正在使用 PDF 打印机进行打印 当调用 Print 时 它不会立即启动 它会等到完成整个子或块的运行代码 我需要确保我正在打印的文件也完整并继续处理该文件
  • 将数组作为参数传递

    如果我们修改作为方法内参数传递的数组的内容 则修改是在参数的副本而不是原始参数上完成的 因此结果不可见 当我们调用具有引用类型参数的方法时 会发生什么过程 这是我想问的代码示例 using System namespace Value Re
  • 我可以在“字节数”设置为零的情况下调用 memcpy() 和 memmove() 吗?

    当我实际上没有什么可以移动 复制的时候 我是否需要处理这些情况memmove memcpy 作为边缘情况 int numberOfBytes if numberOfBytes 0 memmove dest source numberOfBy
  • 如何将十六进制字符串转换为无符号长整型?

    我有以下十六进制值 CString str str T FFF000 如何将其转换为unsigned long 您可以使用strtol作用于常规 C 字符串的函数 它使用指定的基数将字符串转换为 long long l strtol str
  • 不区分大小写的字符串比较 C++ [重复]

    这个问题在这里已经有答案了 我知道有一些方法可以进行忽略大小写的比较 其中涉及遍历字符串或一个good one https stackoverflow com questions 11635 case insensitive string

随机推荐

  • 调整大型结构向量大小时的分割错误

    下面的代码生成分段错误 我不明白为什么 下面的代码使用向量来存储多个大型结构 但代码无法运行并生成分段错误 我不明白为什么 我的理解是向量调整大小在堆中分配内存 因此这不应该是堆栈溢出问题 我的系统具有非常大的物理内存 256 GB 并且代
  • WooCommerce:根据运输方式自动完成付款订单

    我有一种产品 人们可以直接打印 运送方式 1 或选择通过运送服务获取 运送方式 2 因此 如果他们选择仅直接打印 送货方式 2 订单应该自动完成 是否可以从 WooCommerce 扩展该代码片段 从我找到的文档中this https do
  • Apache POI - Word (docx) 文档中的多列

    我正在尝试创建一个包含多列的Word文档 这样做 而不是使用表格 的原因是数据将跨越多个页面 并且只有使用列我才能在添加到新页面之前填充整个页面 可以用 Apache POI 来完成吗 谢谢 使用先前创建的具有多列的空文档怎么样 像这样 X
  • 根据条件降序排列

    我想编写一个 LINQ to Entity 查询 它根据输入参数按升序或降序排序 有什么办法吗 以下是我的代码 请建议 public List
  • 当未初始化的内存传递给函数时如何断言/测试

    我遇到过这样的情况 有时发现我的部分代码传递了未初始化的内存 我正在寻找一种在使用调试堆运行时发生这种情况时可以断言的方法 这是一个可以在其他地方抛出的函数 以提供跟踪错误的额外帮助 void foo char data int dataB
  • jqplot、highcharts、flot如何从轴刻度处捕获点击事件

    我希望能够捕获与所有轴刻度挂钩的单击事件 这是我到目前为止所做的 http jsfiddle net grVFk 5074 http jsfiddle net grVFk 5074 如果有人知道如何使用任何图表插件来做到这一点 请分享 th
  • QtToolBar 按钮文本中带有下划线快捷键

    我有一个简单的 Qt 工具栏 带有纯文本按钮Action MainWindow MainWindow QWidget parent QMainWindow parent QToolBar toolBar new QToolBar this
  • 使用SoupStrainer选择性解析

    我正在尝试解析购物网站上的视频游戏标题列表 然而 由于项目列表全部存储在标签内 This http www crummy com software BeautifulSoup documentation html Improving 20P
  • 特定页面的访问者数量

    我想查看特定页面 我有该页面的 URL 上的访问者数量 我在 Analytics 中找不到输入 URL 来查找该特定页面的统计信息的位置 Go to Behavior gt Site Content gt All Pages and put
  • matlab中矩阵的排序

    我正在对矩阵进行模拟 假设是 5x5 矩阵 该矩阵的元素之一是已知的 下面的后方块 该位置不会始终位于中心 我想从该位置开始并螺旋式访问其他元素 我已按数字显示了顺序 如何在大矩阵 例如 1000x1000 中定义这个顺序 因为我无法手动完
  • 如何从 numpy 数组的每一行中仅获取第一个 True 值?

    我有一个 4x3 布尔 numpy 数组 我试图返回一个相同大小的数组 除了原始数组每行上第一个 True 值的位置之外 该数组全部为 False 所以如果我有一个起始数组 all bools np array False True Tru
  • 某些图像未在移动浏览器中显示(但在桌面浏览器中显示)

    我遇到的问题是 某些图像无法在 iPhone 上的移动浏览器中显示 但我可以在所有桌面浏览器中看到它们 在我的手机上 我只看到一个带有灰色边框的空白框 该图像应该在该位置 一些注意事项 这似乎是随机发生的 因为有些图像在一天显示 然后在第二
  • 如何将 ArrayList 传递给另一个应用程序中的活动?

    我正在尝试在两个应用程序之间共享数据 首先我想到将文件保存到SD卡然后读取它 但是这个解决方案不起作用 所以如果有办法发送一个文件 我会受伤ArrayList of an Object实现Parcelable 还可以采取什么其他方式来实现这
  • 我是否需要显式重载接受 const 左值引用作为右值引用的方法?

    目前我正在尝试右值引用 C 11 g 和 gnu x0 并且我想在我的类中实现移动语义 因为它感觉 正确 我是否需要重载通常接受 const 左值引用的每个函数才能从右值引用中受益 假设这是我的示例类 class Person public
  • 使用并行库添加到列表时保证线程安全的正确方法

    我循环访问连接字符串数组 并在每个循环中提取一些信息并将其添加到列表中 现在 我想使用并行库使其成为多线程 但我不确定该库是否保证对列表的写入是线程安全的 或者我是否需要使用锁定 List
  • 如何在django中调试ajax请求

    我知道例如 def home request if request method POST k p 1 return HttpResponse simplejson dumps dict mimetype application javas
  • Vim:将选定的文本通过管道传输到 shell cmd 并在 vim 信息/命令行上接收输出

    我想将选定的文本通过管道传输到 shell 命令并在 vim 信息 命令行上接收此 shell 命令的一行输出 我真正想做的事情 将选定的文本通过管道传输到pastebin类型的shell命令 并且我想接收shell cmd的输出 这是pa
  • 如何更改 Jekyll 网站的默认字体

    我是使用 Jekyll css 等的新手 我分叉了现在的杰基尔 https github com barryclark jekyll now回购 有没有办法可以更改或添加整个 jekyll 网站的默认字体 看起来像这个帖子 https st
  • 从另一个文本文件中读取基于键的文本文件作为列

    我是 Spark 新手 我正在尝试将表作为文本文件加载到 Spark 中 我想读取基于另一个文本文件列的文本文件 例如 Id 作为键 如果 B id 匹配 A id 那么我必须将文件 B 读入 Spark val file2 sc text
  • 即使设置了 CommandParameter,ICommand.CanExecute 也会传递 null

    我有一个棘手的问题 我正在绑定ContextMenu到一组ICommand 派生对象 并设置Command and CommandParameter每个属性MenuItem通过样式