在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传递相关推荐

  1. 了解 WPF 中的路由事件和命令

    目录 路由事件概述 WPF 元素树 事件路由 路由事件和组合 附加事件 路由命令概述 操作中的路由命令 命令路由 定义命令 命令插入 路由命令的局限 避免命令出错 超越路由命令 路由处理程序示例 要想 ...

  2. WPF中的路由事件(转)

    出处:https://www.cnblogs.com/JerryWang1991/archive/2013/03/29/2981103.html 最近因为工作需要学习WPF方面的知识,因为以前只关注的 ...

  3. WPF 中的 loaded 事件和 Initialized 事件

    在 WPF 中, 控件有 Loaded 和 Initialized 两种事件. 初始化和加载控件几乎同时发生, 因此这两个事件也几乎同时触发. 但是他们之间有微妙且重要的区别. 这些区别很容易让人误解 ...

  4. python鼠标事件 详解_Python selenium键盘鼠标事件实现过程详解

    引言 ----在实际的web测试工作中,需要配合键盘按键来操作,webdriver的 keys()类提供键盘上所有按键的操作,还可以模拟组合键Ctrl+a,Ctrl+v等. 举例: #cording= ...

  5. 鼠标处显示坐标 html,cesium的鼠标事件(最基础的显示鼠标位置坐标)

    一.cesium屏幕空间事件控制者接口:ScreenSpaceEventHandler(参数canvas) #var handler = new Cesium.ScreenSpaceEventHand ...

  6. js中jquery鼠标事件(点击替换、鼠标移入、移出)

    1.先添加三张图片 <img src="./vscode/images/1.jpg" width="300"><img src=". ...

  7. PHPStudy(小皮)V8.1 中使用cmd进入MySQL命令行模式

    1.找到phpstudy_pro中的mysql可执行文件所在的位置(安装位置) 把这个路径进行复制:D:\phpstudy_pro\Extensions\MySQL5.7.26\bin 2.输入命令m ...

  8. WPF 触屏事件后触发鼠标事件的问题及 DataGrid 误触问题

    WPF 触屏事件后触发鼠标事件的问题及 DataGrid 误触问题 目录 一.触屏事件连带触发鼠标事件的问题 二.DataGrid 误触问题及解决方法 独立观察员 2021 年 10 月 10 日 一 ...

  9. WPF中路由事件的传播

    路由事件(RoutedEvent)是WPF中新增的事件,使用起来与传统的事件差别不大, 但传播方式是完全不同的. 路由事件的传播方式 通过RoutingStrategy来定义传播的方式 public ...

最新文章

  1. 如何站在使用者的角度来设计SDK-微信公众号开发SDK(消息处理)设计之抛砖引玉...
  2. python线程卡死问题解决_python while True造成未响应或卡顿的解决方法
  3. matplotlib可视化必知必会富文本绘制方法
  4. java中定时器的使用
  5. linux mysql ibd_MySQL:如何从ibd文件中恢复数据
  6. 【2018ACM山东省赛 - C】Cities(最小生成树变形优化,贪心思维)
  7. 数据解读京东上最受欢迎的面包
  8. redis与memcached区别
  9. 数据结构与算法之-----栈的应用(三)
  10. TCP握手协议的巧计方法
  11. iOS开发常用的RGB色值
  12. CeBIT亮点:IBM“绿色地平线” 战斗在雾霾治理的科技前线
  13. 2019年密码与安全新技术讲座-课程总结报告
  14. Ghost xp NetMeeting不能共享桌面的解决办法
  15. 渗透测试-安全岗位面试题总结(含答案)
  16. 防手机锁屏解锁自定义View
  17. 红旗linux shell方式下配置声卡的命令是:,linux基础知识1
  18. 【JS】去除“确认重新提交表单”
  19. python 单斜杠/和双斜杆//的区别
  20. Spring Cloud Gateway网关实战

热门文章

  1. 【ipad】ipad如何与电脑连接
  2. 菜鸟驿站下一站:跟美团抢社区生意
  3. 举例说明一下常见的弱口令_常见网站入侵手段及防御方法
  4. 【English】七月英语总结
  5. 简笔彩色圣诞树的python代码_Python画一棵漂亮的樱花树(不同种樱花+玫瑰+圣诞树喔)...
  6. 网络教学资源平台设计与实现--用例图(初稿)
  7. 由华晨宇怼李袁杰谈谈什么是「职业素养」
  8. 下单账号与支付账号不一致_【支付宝】如何申请支付账号
  9. ME60单板加载故障维护经验
  10. 基于Kolla-ansible部署openstack容器化部署(all-in-one)