原文:WPF 的命令的自动刷新时机——当你 CanExecute 会返回 true 但命令依旧不可用时可能是这些原因

在 WPF 中,你可以使用 Command="{Binding WalterlvCommand}" 的方式来让 XAML 中的一个按钮或其他控件绑定一个命令。这样,按钮的可用性会自动根据 WalterlvCommand 当前 CanExecute 的状态来改变。这本是一个非常智能的特性,直到你可能发现你按钮的可用性状态不正确……

本文介绍默认情况下,WPF 在 UI 上的这些命令会在什么时机进行刷新;以及没有及时刷新时,可以如何强制让这些命令的可用性状态进行刷新。了解了这些,你可能能够解决你在 WPF 程序中命令绑定的一些坑。


This post is written in multiple languages. Please select yours:

一个最简单的例子

<Button x:Name="TestCommand" Command="{Binding WalterlvCommand}" />
  • 1
public class Walterlv
{
// 省略了此命令的初始化。
public WalterlvCommand WalterlvCommand { get; }
} public class WalterlvCommand : ICommand
{
public bool SomeFlag { get; set; } bool ICommand.CanExecute(object parameter)
{
// 判断命令的可用性。
return SomeFlag;
} void ICommand.Execute(object parameter)
{
// 省略了执行命令的代码。
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

假如 SomeFlag 一开始是 false,5 秒种后变为 true,那么你会注意到这时的按钮状态并不会刷新。

var walterlv = new Walterlv();
TestCommand.DataContext = walterlv; await Task.Delay(5000);
walterlv.WalterlvCommand.SomeFlag = true;
  • 1
  • 2
  • 3
  • 4
  • 5

当然,以上所有代码会更像伪代码,如果你不熟悉 WPF,是一定编译不过的。我只是在表达这个意思。

如何手动刷新命令

调用以下代码,即可让 WPF 中的命令刷新其可用性:

CommandManager.InvalidateRequerySuggested();
  • 1

WPF 的命令在何时刷新?

默认情况下,WPF 的命令只会在以下时机刷新可用性:

  • KeyUp
  • MouseUp
  • GotKeyboardFocus
  • LostKeyboardFocus

使用通俗的话来说,就是:

  • 键盘按下的按键抬起的时候
  • 在鼠标的左键或者右键松开的时候
  • 在任何一个控件获得键盘焦点或者失去键盘焦点的时候

这部分的代码可以在这里查看:

最关键的代码贴在这里:

// 省略前面。
if (e.StagingItem.Input.RoutedEvent == Keyboard.KeyUpEvent ||
e.StagingItem.Input.RoutedEvent == Mouse.MouseUpEvent ||
e.StagingItem.Input.RoutedEvent == Keyboard.GotKeyboardFocusEvent ||
e.StagingItem.Input.RoutedEvent == Keyboard.LostKeyboardFocusEvent)
{
CommandManager.InvalidateRequerySuggested();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

然而,并不是只在这些时机进行刷新,还有其他的时机,比如这些:


我的博客会首发于 https://blog.walterlv.com/,而 CSDN 会从其中精选发布,但是一旦发布了就很少更新。

如果在博客看到有任何不懂的内容,欢迎交流。我搭建了 dotnet 职业技术学院 欢迎大家加入。

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名吕毅(包含链接:https://walterlv.blog.csdn.net/),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系

发布了382 篇原创文章 · 获赞 232 · 访问量 47万+

WPF 的命令的自动刷新时机——当你 CanExecute 会返回 true 但命令依旧不可用时可能是这些原因的更多相关文章

  1. 浏览器自动刷新——基于Nodejs的Gulp LiveReload与VisualStudio完美结合。

    本文版权桂博客园和作者吴双共同所有,转载和爬虫请注明原文地址 http://www.cnblogs.com/tdws/p/6016055.html 写在前面 大家好我是博客园的蜗牛,博客园的蜗牛就是我 ...

  2. Sublime3和Chrome配置自动刷新网页【实测可用】

    SublimeText2下的LiveReload在SublimeText3下无法正常使用,本文整理SublimeText3安装LiveReload的方法.win7下实测可用! 安装成功后,就不需要再手 ...

  3. gulp之压缩合并MD5清空替换加前缀以及自动编译自动刷新浏览器大全

    gulp是基于流的前端构件化工具.目前比较火的前端构建化工具还是挺多的,grunt gulp fis3等等. 这个鬼东西有什么用?请参考https://www.zhihu.com/question/3 ...

  4. SQL实现类似于自动刷新数据的功能

    有时需要在SQL中,定时刷新某张表,比如说是要定时查询某张表的行数,通常做法就是手动的按F5去执行来刷新数据.但是如果这个定时查询历时较长,10分钟,或半小时,手动的话肯定是要崩溃了.貌似SQL没有像 ...

  5. Windows Phone 8 LongListSelector实现下拉自动刷新列表

    LongListSelector是一个加强版的列表控件,它可以实现分组的列表,如系统人脉列表的交互效果就可以利用LongListSelector控件去实现,同时LongListSelector也一样可 ...

  6. gulp自动刷新插件

    gulp自动刷新的插件很多,但是感觉最好用的还是 browser-sync 插件.如果不想用命令行,也可以使用 browser-sync界面工具 先安装 browser-sync 插件: npm in ...

  7. BrowserSync,调试利器--自动刷新(转

    ---恢复内容开始--- 请想象这样一个场面:你开着两个显示器,一边是IDE里的代码,另一边是浏览器里的你正在开发的应用.此时桌上还放着你的手机,手机里也是这个开发中的应用.然后,你新写了一小段代码, ...

  8. gulp+browserSync+nodemon 实现express 全端自动刷新的实践

    学习过程宝宝心里苦,不能怨政府.. 兴趣所致,一直放不下nodejs的学习,时隔多日,又把express捡起来打算重新再学学,一直没什么太大的长进,和实际的项目经验.真的醉了,太懒了. 今天在重新研究 ...

  9. gulp最佳实践(包含js,css,html预编译,合并,压缩,浏览器自动刷新)

    gulp是基于流的自动化构建工具官方网址:http://www.gulpjs.com.cn/ 一.安装需要的模块 1.新建package.json,输入下面的内容 { "name" ...

随机推荐

  1. shell 查找字符串中字符出现的位置

    #!/bin/bash a="The cat sat on the mat" test="cat" awk -v a="$a" -v b=& ...

  2. 初始化错误——从一个简单的算例看UDF各个宏的调用顺序

    感谢西安交通大学en_phert的问题和尝试 Fluent版本:Fluent 19.0 Visual Studio版本:Visual Studio 2013 在UDF的宏的调用中大家常看见下图: 这个 ...

  3. epool与select有什么区别

    select在一个进程中打开的最大fd是有限制的,由FD_SETSIZE设置,默认值是2048.不过 epoll则没有这个限制,它所支持的fd上限是最大可以打开文件的数目,这个数字一般远大于2048, ...

  4. 微信小程序诡异错误this.setData报错

    先说原因: function声明的函数和箭头函数的作用域不同,这是一个不小心坑的地方.可参考箭头函数说明:https://developer.mozilla.org/en-US/docs/Web/Ja ...

  5. 面试突击(五)——Java常用集合

    为了勾起回忆,我画了一个常用集合类的结构关系图,话不多说,详见下图: 实际开发中ArrayList/HashMap/HashSet是三种最常用的集合工具类,通过其结构关系图也能清晰的了解他们的特性,所 ...

  6. 一行命令搞定/usr/bin/perl^M: bad interpreter

    https://www.cnblogs.com/albertYe/p/8819143.html **************************************************** ...

  7. Kafka限流

    1. 客户端认证 如果kafka客户端是认证的,那么可以使用userId和clientId两种认证方式.如果没有认证只能使用clientId限流. bin/kafka-configs. --alter ...

  8. Win7下Powershell 由2.0 升级为 5.1

    今天在构建脚本的时候老是提示 Windows 7 默认的Powershell是2.0,查看版本 下载 https://www.microsoft.com/en-us/download/details. ...

  9. 小甲鱼汇编语言学习笔记——day03

    手动编译并执行第一个汇编程序过程: 1.用notepad++写一个简单的汇编程序(文件命名为:1.asm): assume cs:abc abc segment mov ax, 2 add ax, a ...

  10. django数据库配置,即数据库分库分表

    一 Django的数据库配置 (一)修改settings.py文件关于数据库的配置: Django默认使用sqlite:   DATABASES = { 'default': { 'ENGINE': ...