WPF中对鼠标事件转换为命令处理模式的鼠标位置参数传递及EventArgs传递
在WPF中使用命令模型,对于实现ICommandSource的元素来讲,比较方便,对于未实现ICommandSouce的元素来讲可以利用Blend中提供的行为来解决。通常情况下,命令对象可以传递命令参数(CommandParameter),如果将鼠标事件用命令来解决,则往往需要关注鼠标的位置,如果在事件处理方法中可以通过MouseEventArgs对象来获取。那如果在命令中获取鼠标位置呢,可能有多种解决方法,本文主要介绍一种利用Mouse.GetPosition(IInputElement)方法来获取鼠标相对于WPF元素的位置,以及利用Win32API 函数GetCursorPos()来获取屏幕鼠标位置的方法。
Xaml代码如下:
<Window.Resources>
<vm:MyViewModel x:Key="myViewModel"></vm:MyViewModel>
</Window.Resources>
<StackPanel DataContext="{StaticResource myViewModel}">
<Label Name="label" Content="my"/>
<Canvas Name="canvas" Height="400" MouseMove="btn_MouseMove" Background="AliceBlue">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDown">
<i:InvokeCommandAction Command="{Binding ShowMessageBoxCommand}" CommandParameter="{Binding ElementName=canvas}" />//将canvas作为参数传入,在viewmodel中通过Mouse.GetPosition(canvas)来获取鼠标位置
//说明:此处如果换成Prism库中的InvokeCommandAction,则可以直接将EventArgs对象属性或对象本身传递给Command, 例如在集合控件ListBox中写成<prism:InvokeCommandAction Command={Binding SelectedCommand}" TriggerParameterPath="AddedItems"/>,此处的AddedItems就是SelectionChangedEventArgs对象的属性,这样就可以把EventArgs对象属性传递给了命令,在viewModel中处理命令对象就可以很方便的获取到事件对象的属性。如果直接传递EventArs对象,则省略TriggerParameterPath属性或者将该属性写成TriggerParameterPath=""即可。(个人理解:做MVVM开发时,尽量不要将界面控件如Canvas或WPF事件对象EventArgs直接传递给ViewModel,这会造成ViewModel对象对界面控件类型的依赖,尽可能仅传递所用到的事件对象的参数即可)
补充:如果采用Prism库中的prism:InvokeCommandAction,那么就可以传递TriggerParameterPath,可以把事件对象本身或事件对象的属性作为CommandParameter传递给ViewModel中的DelegateCommand对象,就不用把界面元素传给ViewModel了。参考:https://blog.csdn.net/jiuzaizuotian2014/article/details/104845775
</i:EventTrigger>
<i:EventTrigger EventName="MouseMove">
<i:InvokeCommandAction Command="{Binding ShowScreenMousePositionCommand}" CommandParameter="{Binding ElementName=label}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Canvas>
</StackPanel>
在ViewModel中的代码如下:
public class MyViewModel:BindableBase
{
private string _myProperty = "";
public string MyProperty { get { return _myProperty; } set { SetProperty(ref _myProperty, value);
RaisePropertyChanged();
} }
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool GetCursorPos(out POINT pt);
public struct POINT
{
public int X;
public int Y;
public POINT(int x, int y)
{
this.X = x;
this.Y = y;
}
}
public ICommand ShowMessageBoxCommand
{
get
{
return new DelegateCommand<Canvas>((c) => { //DelegateCommand<T>来自于Prism框架
Point p = Mouse.GetPosition(c);
MessageBox.Show($"x={p.X},y={p.Y}"); //显示鼠标在Canvas上的位置
});
}
}
public ICommand ShowScreenMousePositionCommand
{
get
{
return new DelegateCommand<Label>((c) => {
POINT p = new POINT(); //利用自定义的POINT结构体,参数类型为整数。
//注:System.Windows.Point结构体的参数是浮点
GetCursorPos(out p);//利用win32API获取鼠标在显示屏上的位置
c.Content = string.Format("{0},{1}", p.X, p.Y);
});
}
}
}
}
WPF中对鼠标事件转换为命令处理模式的鼠标位置参数传递及EventArgs传递相关推荐
- 了解 WPF 中的路由事件和命令
目录 路由事件概述 WPF 元素树 事件路由 路由事件和组合 附加事件 路由命令概述 操作中的路由命令 命令路由 定义命令 命令插入 路由命令的局限 避免命令出错 超越路由命令 路由处理程序示例 要想 ...
- WPF中的路由事件(转)
出处:https://www.cnblogs.com/JerryWang1991/archive/2013/03/29/2981103.html 最近因为工作需要学习WPF方面的知识,因为以前只关注的 ...
- WPF 中的 loaded 事件和 Initialized 事件
在 WPF 中, 控件有 Loaded 和 Initialized 两种事件. 初始化和加载控件几乎同时发生, 因此这两个事件也几乎同时触发. 但是他们之间有微妙且重要的区别. 这些区别很容易让人误解 ...
- python鼠标事件 详解_Python selenium键盘鼠标事件实现过程详解
引言 ----在实际的web测试工作中,需要配合键盘按键来操作,webdriver的 keys()类提供键盘上所有按键的操作,还可以模拟组合键Ctrl+a,Ctrl+v等. 举例: #cording= ...
- 鼠标处显示坐标 html,cesium的鼠标事件(最基础的显示鼠标位置坐标)
一.cesium屏幕空间事件控制者接口:ScreenSpaceEventHandler(参数canvas) #var handler = new Cesium.ScreenSpaceEventHand ...
- js中jquery鼠标事件(点击替换、鼠标移入、移出)
1.先添加三张图片 <img src="./vscode/images/1.jpg" width="300"><img src=". ...
- PHPStudy(小皮)V8.1 中使用cmd进入MySQL命令行模式
1.找到phpstudy_pro中的mysql可执行文件所在的位置(安装位置) 把这个路径进行复制:D:\phpstudy_pro\Extensions\MySQL5.7.26\bin 2.输入命令m ...
- WPF 触屏事件后触发鼠标事件的问题及 DataGrid 误触问题
WPF 触屏事件后触发鼠标事件的问题及 DataGrid 误触问题 目录 一.触屏事件连带触发鼠标事件的问题 二.DataGrid 误触问题及解决方法 独立观察员 2021 年 10 月 10 日 一 ...
- WPF中路由事件的传播
路由事件(RoutedEvent)是WPF中新增的事件,使用起来与传统的事件差别不大, 但传播方式是完全不同的. 路由事件的传播方式 通过RoutingStrategy来定义传播的方式 public ...
最新文章
- 如何站在使用者的角度来设计SDK-微信公众号开发SDK(消息处理)设计之抛砖引玉...
- python线程卡死问题解决_python while True造成未响应或卡顿的解决方法
- matplotlib可视化必知必会富文本绘制方法
- java中定时器的使用
- linux mysql ibd_MySQL:如何从ibd文件中恢复数据
- 【2018ACM山东省赛 - C】Cities(最小生成树变形优化,贪心思维)
- 数据解读京东上最受欢迎的面包
- redis与memcached区别
- 数据结构与算法之-----栈的应用(三)
- TCP握手协议的巧计方法
- iOS开发常用的RGB色值
- CeBIT亮点:IBM“绿色地平线” 战斗在雾霾治理的科技前线
- 2019年密码与安全新技术讲座-课程总结报告
- Ghost xp NetMeeting不能共享桌面的解决办法
- 渗透测试-安全岗位面试题总结(含答案)
- 防手机锁屏解锁自定义View
- 红旗linux shell方式下配置声卡的命令是:,linux基础知识1
- 【JS】去除“确认重新提交表单”
- python 单斜杠/和双斜杆//的区别
- Spring Cloud Gateway网关实战
热门文章
- 【ipad】ipad如何与电脑连接
- 菜鸟驿站下一站:跟美团抢社区生意
- 举例说明一下常见的弱口令_常见网站入侵手段及防御方法
- 【English】七月英语总结
- 简笔彩色圣诞树的python代码_Python画一棵漂亮的樱花树(不同种樱花+玫瑰+圣诞树喔)...
- 网络教学资源平台设计与实现--用例图(初稿)
- 由华晨宇怼李袁杰谈谈什么是「职业素养」
- 下单账号与支付账号不一致_【支付宝】如何申请支付账号
- ME60单板加载故障维护经验
- 基于Kolla-ansible部署openstack容器化部署(all-in-one)