【wpf】Command Binding 命令绑定的使用
前言
这次讲解的命令绑定,主要解决的问题是,为实现MVVM模式进行铺垫,实现前后台逻辑的解耦。
我们知道如果Button直接实现Click事件,那么实现的逻辑必然在Window后台代码中,为了实现MVVM,我要将业务逻辑放在ViewMode里面,这时需要Command Binding。
Command Binding
使用Command 替换 Click
前台代码:
<Button Grid.Row="2"
Command="{Binding BtnSaveCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Self}}">保存</Button>
创建CommandBase类
然后创建CommandBase类,该类实现ICommand接口。
ICommand需要实现一个事件:CanExecuteChanged
两个方法: Execute, CanExecute
Execute 是命令促发后,系统会调用的回调函数
CanExecute 是当CanExecuteChanged事件触发后,体统会调用它,并更具它的返回值判断控件是否可用。
public class CommandBase : ICommand
{
public event EventHandler CanExecuteChanged;
public Action<object> DoExecute { get; set; }
// 这里给个默认的值,不实现就返回true
public Func<object, bool> DoCanExecute { get; set; } = new Func<object, bool>(obj => true);
public bool CanExecute(object parameter)
{
// 让实例去实现这个委托
return DoCanExecute?.Invoke(parameter) == true;// 绑定的对象 可用
}
public void Execute(object parameter)
{
// 让实例去实现这个委托
DoExecute?.Invoke(parameter);
}
//目的 就是触发一次CanExecuteChanged事件
public void DoCanExecuteChanged()
{
// 触发事件的目的就是重新调用CanExecute方法
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
}
ViewMode中实例化命令
public CommandBase BtnSaveCommand { get; set; }
public ConfigInfoViewMode()
{
BtnSaveCommand = new CommandBase()
{
DoExecute = new Action<object>(SaveTo),
DoCanExecute = new Func<object, bool>(CanSave)
};
}
//最终按钮会触发到改函数
void Save(object obj)
{
}
//决定按键是否可用(这也是命令额外的一个作用)
// 通过调用DoCanExecuteChanged,可以触发该元素
public bool CanSave(object obj)
{
return true;
}
事件触发
//目的 就是触发一次CanExecuteChanged事件
public void DoCanExecuteChanged()
{
// 触发事件的目的就是重新调用CanExecute方法
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
触发事件的目的就是重新调用CanExecute方法,从而从新判断控件是否可用。
但是这个DoCanExecuteChanged(),是需要我们人为调用的。
CommandManager
如果不想手动调用DoCanExecuteChanged(),还有一个办法就是CommandManager。
另外一种写法可以让系统去调用,我们需要一个新的知识点CommandManager
以下两种写法都可以,只需要在定义CanExecuteChanged时稍微改动一下:
// 通知:当前按钮检查可用条件 触发 一次CanExecute
// 写法一
public event EventHandler? CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
//写法二
public event EventHandler? CanExecuteChanged
{
add => CommandManager.RequerySuggested += value;
remove => CommandManager.RequerySuggested -= value;
}
这里的意思是,通过静态变量CommandManager将CanExecuteChanged挂载到,RequerySuggested 这个事件上,这里的value是指CanExecuteChanged本身,下图可以证明。(这个和属性的value有着异曲同工之妙)
从此之后,这个检测调用的工作交给系统。
我发现这个检测的时机其实和绑定有关。
<TextBox Text="{Binding mainModel.Value1,UpdateSourceTrigger=PropertyChanged}"/>
<TextBox Text="{Binding mainModel.Value3}"/>
我们在检擦函数中这么写的:
// Hello命令的的可用判断逻辑
public bool CanHello(object obj)
{
// 命令可用条件
// 当调用 CanExecuteChanged 事件后,重新进行条件检查
return this.mainModel.Value1 != 0;
}
public bool CanWorld(object obj)
{
return this.mainModel.Value3 != 0;
}
也就是说,TextBox中的值会决定Button是否可用!
那么第一个TextBox的值,只要一发生改变,那么就会触发检查是否可用,而第二个TextBox只有
失去焦点的时候,才会触发检查。
这里有个小疑问,我们的Command是写在Button上的,所以判断是Button是否可用,同时Command实现了CanExecuteChanged事件,并挂载到了全局,以便系统调用,那系统是怎么知道
变化的Value和Button的关系的呢?也不知道微软是什么时候将这个指和Button关联上的。
强制触发
当然,此时如果你觉得你想在某个时刻进行强制触发检测,也是可以的,还是使用CommandManager这个静态变量:
CommandManager.InvalidateRequerySuggested();
鼠标和键盘
写道这里,其实还存在一个问题,Button的Command是由但是触发的,如果我想通过双击或者快捷键触发怎么办呢?
InputBindings
InputBindings,满足你的需求:
<Button Content="Button">
<Button.InputBindings>
<MouseBinding MouseAction="LeftDoubleClick"
Command="{Binding Btn1Command}"
CommandParameter="123"/>
<KeyBinding Key="Q" Modifiers="Alt"
Command="{Binding Btn1Command}"
CommandParameter="123"/>
</Button.InputBindings>
</Button>
MouseBinding 中的MouseAction还有如下操作:
- 单击鼠标左键 :LeftClick
- 双击鼠标左键:LeftDoubleClick
- 单击鼠标中键 :MiddleClick
- 双击鼠标中键:MiddleDoubleClick
- 单击鼠标右键:RightClick
- 双击鼠标右键:RightDoubleClick
- 不执行任何操作:None
- 旋转鼠标滚轮:WheelClick
KeyBinding
KeyBinding 可以帮我们实现快捷键和快捷键组合,简直完美~~。
作者:宋桓公
出处:http://www.cnblogs.com/douzi2/
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南