title author date CreateTime categories
WPF 绑定命令在 MVVM 的 CanExecute 和 Execute 在按钮点击都没触发可能的原因
lindexi
2019-5-8 10:3:36 +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-5-8-WPF-绑定命令在-MVVM-的-CanExecute-和-Execute-在按钮点击都没触发可能的原因...的更多相关文章

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

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

  2. WPF绑定命令

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

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

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

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

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

  5. WPF 在事件中绑定命令

    导航:MVVMLight系列文章目录:<关于 MVVMLight 设计模式系列> 其实这也不属于MVVMLight系列中的东东了,没兴趣的朋友可以跳过这篇文章,本文主要介绍如何在WPF中实 ...

  6. WPF之事件绑定命令

    目录 事件绑定意义 无参数的事件绑定 带EventArgs参数的事件绑定 使用事件绑定 扩展:基于InvokeCommandAction源码的实现(推荐) 参考资料 事件绑定意义 一般事件的处理程序都 ...

  7. wpf绑定全局静态变量(mvvm)

    原文 wpf绑定全局静态变量(mvvm) 在实际的开发中,有一些集合或者属性可能是全局的,比如当你做一个oa的时候,可能需要展示所有的人员,这时这个所有的人员列表显然可以作为全局参数,比如这里有一个全 ...

  8. 整理:WPF中应用附加事件制作可以绑定命令的其他事件

    原文:整理:WPF中应用附加事件制作可以绑定命令的其他事件 目的:应用附加事件的方式定义可以绑定的事件,如MouseLeftButton.MouseDouble等等 一.定义属于Control的附加事 ...

  9. 整理:WPF用于绑定命令和触发路由事件的自定义控件写法

    原文:整理:WPF用于绑定命令和触发路由事件的自定义控件写法 目的:自定义一个控件,当点击按钮是触发到ViewModel(业务逻辑部分)和Xaml路由事件(页面逻辑部分) 自定义控件增加IComman ...

随机推荐

  1. swapper_pg_dir的作用

    在内存系统初始化过程中,有如下代码: 1: static void __init pagetable_init(void) 2: { 3: pgd_t *pgd_base = swapper_pg_d ...

  2. KMP概念上小结

    kmp算法的时间复杂度是O(m+n) 主要作用: 1.最长公共前后缀问题 2.原串中含有几个模式串问题 3.循环节问题

  3. k8s 资源管理

    对应到Kubernetes的Pod容器上,就是下面这4个参数:◎ spec.container[].resources.requests.cpu:◎ spec.container[].resource ...

  4. leetcode.哈希表.594最长和谐子序列-Java

    1. 具体题目: 和谐数组是指一个数组里元素的最大值和最小值之间的差别正好是1.现在,给定一个整数数组,你需要在所有可能的子序列中找到最长的和谐子序列的长度. 示例 1: 输入: [1,3,2,2,5 ...

  5. sublimeText3的安装及插件的配置使用

    这里主要记录一些关于sublime text的配置,并且参照了别人的博客归纳的. 一.下载sublime text   http://www.sublimetext.com/3二.安装Package ...

  6. PD ZD

    PD TO ZD simple one without . SORT FIELDS,,PD,A,,,PD,A) OUTREC FIELDS,,PD,ZD,LENGTH, ,,PD,ZD,LENGTH, ...

  7. tf.matmul() 和tf.multiply() 的区别

    1.tf.multiply()两个矩阵中对应元素各自相乘 格式: tf.multiply(x, y, name=None) 参数: x: 一个类型为:half, float32, float64, u ...

  8. ubuntu phpize 安裝

    php 版本 7.2,所以安裝 php7.2的 sudo apt-get install php7.2-dev 參考 Is is possible to install phpize for PHP7 ...

  9. jQuery实现全选与全部选

    为了便于用户理解,直接粘贴下面的代码即可 <!DOCTYPE html> <html lang="en"> <head> <meta ch ...

  10. IIS查找报错信息

    1.打开IIS,选择日志 2.选择 日志文件和ETW事件   ---->应用 3.在发布网站的根目录下找一个logs文件(如果没有则创建) 4.浏览网站,如果报错,logs文件夹下面就会生成一个 ...