原文:2019-11-29-WPF-绑定命令在-MVVM-的-CanExecute-和-Execute-在按钮点击都没触发可能的原因...

title author date CreateTime categories
WPF 绑定命令在 MVVM 的 CanExecute 和 Execute 在按钮点击都没触发可能的原因
lindexi
2019-11-29 08:48:48 +0800
2019-05-08 08:58:28 +0800
WPF

在 WPF 推荐使用 MVVM 绑定命令,但是绑定命令会存在很多坑,其中一个就是焦点的问题。如果在用户点击按钮的时候出现了焦点修改,那么此时的命令是不会被触发

在命令绑定按钮点击的时候,会触发按钮拿到键盘焦点,此时其他元素如果之前有拿到焦点,那么会触发元素失去焦点。如果在元素一次 Dispatcher 的过程重新拿到焦点,那么按钮的命令将不会被触发

说起来复杂,因为在项目的代码是很复杂很难直接看到这个问题,所以我建议创建一个新的 WPF 项目,不要引用任何小伙伴框架,简单定义一些类就可以看到这个坑

定义一个简单的命令

    public class Command : ICommand
{
/// <inheritdoc />
public bool CanExecute(object parameter)
{
return true;
} /// <inheritdoc />
public void Execute(object parameter)
{
Debug.WriteLine("林德熙是逗比");
} /// <inheritdoc />
public event EventHandler CanExecuteChanged;
}

定义一个简单的 ViewModel 里面只有命令

    public class ViewModel
{
public ICommand Command { get; } = new Command();
}

在界面绑定 ViewModel 请看代码

        public MainWindow()
{
InitializeComponent();
DataContext = ViewModel;
} public ViewModel ViewModel { get; } = new ViewModel();

如何绑定 ViewModel 请看 win10 uwp DataContext

在界面放一个文本和一个按钮,文本可以在失去焦点的时候重新拿到焦点

        <StackPanel Margin="10,10,10,10">
<TextBox LostFocus="TextBox_OnLostFocus"></TextBox>
<Button Margin="10,10,10,10" Content="确定" Command="{Binding Command}"></Button>
</StackPanel>

后台代码的失去焦点需要通过在一次 Dispatcher 里面写,不然将会出现有趣的坑,具体是什么坑,可以下载我的源代码自己修改一下

请看后台代码

        private void TextBox_OnLostFocus(object sender, RoutedEventArgs e)
{
Dispatcher.InvokeAsync(((UIElement) sender).Focus);
}

此时运行代码,点击文本,可以看到输出窗口输出 林德熙是逗比 然后点击文本,输入文字,然后点击按钮,可以发现按钮的命令没有触发

在命令的 CanExecute 打上断点,可以发现连 CanExecute 都没有进入

如果遇到了在按钮 MVVM 绑定命令,发现命令没有触发,同时 CanExecute 都没有进入,可以猜可能是命令没有初始化、命令没有绑对,还有可能是在过程出现焦点问题

另外不一定是用户直接调用 Focus 其他的 WPF 控件间接修改

源代码放在 github

2019-11-29-WPF-绑定命令在-MVVM-的-CanExecute-和-Execute-在按钮点击都没触发可能的原因...的更多相关文章

  1. 2019-5-8-WPF-绑定命令在-MVVM-的-CanExecute-和-Execute-在按钮点击都没触发可能的原因...

    title author date CreateTime categories WPF 绑定命令在 MVVM 的 CanExecute 和 Execute 在按钮点击都没触发可能的原因 lindexi ...

  2. WPF绑定命令

    一.目的 降低代码耦合度(降低UI层和BLL层的代码耦合度),将UI层的后台代码更好的转移到BLL层中,让视图和业务逻辑分离的更好 二.使用方式 1.创建一个RelayCommand,继承IComma ...

  3. 2019.11.29 Mysql的数据操作

    为名为name的表增加数据(插入所有字段) insert into name values(1,‘张三’,‘男’,20); 为名为name的表增加数据(插入部分字段) insert into name ...

  4. 2019.11.29 SAP SMTP郵件服務器配置 發送端 QQ郵箱

    今天群裏的小夥伴問了如何配置郵件的問題,隨自己在sap裏面配置了一個 1.    RZ10配置參數 a)       参数配置前,先导入激活版本 执行完毕后返回 b)      输入参数文件DEFAU ...

  5. pycharm+anaconda在Mac上的配置方法 2019.11.29

    内心os: 听人说,写blog是加分项,那他就不是浪费时间的事儿了呗 毕竟自己菜还是留下来东西来自己欣赏吧 Mac小电脑上进行python数据开发环境的配置 首先下载Anaconda,一个超好用的数据 ...

  6. Supervision meeting notes 2019/11/29

    topic 分支:  1. subgraph/subsequence mining Wang Jin, routine behavior/ motif. Philippe Fournier Viger ...

  7. EOJ Monthly 2019.11 E. 数学题(莫比乌斯反演+杜教筛+拉格朗日插值)

    传送门 题意: 统计\(k\)元组个数\((a_1,a_2,\cdots,a_n),1\leq a_i\leq n\)使得\(gcd(a_1,a_2,\cdots,a_k,n)=1\). 定义\(f( ...

  8. WPF采用MVVM模式(绑定:纯前台、命令:触发器绑定命令)

    MVVM绑定 view-viewModel-model,模型介绍省略,就是创建类,添加字段封装属性.注:控件的绑定只能绑定到属性上,不能绑定到字段上: 接下来就是代码 (view): <Wind ...

  9. WPF 在事件中绑定命令(不可以在模版中绑定命令)

    其实这也不属于MVVMLight系列中的东东了,没兴趣的朋友可以跳过这篇文章,本文主要介绍如何在WPF中实现将命令绑定到事件中. 上一篇中我们介绍了MVVMLight中的命令的用法,那么仅仅知道命令是 ...

随机推荐

  1. 5.如何基于 dubbo 进行服务治理、服务降级、失败重试以及超时重试?

    作者:中华石杉 面试题 如何基于 dubbo 进行服务治理.服务降级.失败重试以及超时重试? 面试官心理分析 服务治理,这个问题如果问你,其实就是看看你有没有服务治理的思想,因为这个是做过复杂微服务的 ...

  2. docker仓库资源的地址修改

    docker仓库资源的地址修改 1.新增或者修改/etc/docker目录下的daemon.json文件 样例文件如下 { "registry-mirrors": ["h ...

  3. JS高阶---instanceof

    一句话: .

  4. P4677 山区建小学|区间dp

    P4677 山区建小学 题目描述 政府在某山区修建了一条道路,恰好穿越总共nn个村庄的每个村庄一次,没有回路或交叉,任意两个村庄只能通过这条路来往.已知任意两个相邻的村庄之间的距离为di 为了提高山区 ...

  5. 使用spring jdbc遇到的一个性能问题

    使用JdbcTemplate的queryForList方法,返回特别慢,40多万结果集耗时超过6分钟.双核CPU,占用率始终在50%,内存逐渐增长至2G左右. 进行debug跟进去看,看到jdbcTe ...

  6. Windows解决端口占用问题

    Windows解决端口占用问题 步骤 1. win + R,输入cmd回车进入dos界面 2. 输入netstat -ano|findstr 8080 查看占用8080端口的进程 3. 输入taskk ...

  7. CF13B Letter A

    CF13B Letter A 洛谷传送门 题目描述 Little Petya learns how to write. The teacher gave pupils the task to writ ...

  8. itsdangerous模块

    使用场景: 在取消订阅时,可以在URL里序列化并且签名一个用户的ID或在任何的激活账户的链接或类似的情形下使用.这种情况下不需要生成一个一次性的token并把它们存到数据库中. 被签名的对象可以被存入 ...

  9. appium--解决中文输入不了的问题

    配置 from appium import webdriver desired_caps={} desired_caps['platformName']='Android' #模拟器 desired_ ...

  10. UVA10559 方块消除 Blocks 题解

    设g[i][j][k]为消去区间[i,j]中的方块,只留下k个与a[i]颜色相同的方块的最大价值,f[i][j]为将[i,j]中所有方块消去的价值,转移自己yy一下即可. 为什么这样是对的?因为对于一 ...