本文记载在WPF应用中鼠标、触摸混合输入,鼠标事件抬起时不会有MouseUp事件触发的问题。
事件输入我们都知道有3类:鼠标、触摸、触笔,鼠标是windows体系出来就有的事件,后面加了触笔、触摸。
1.鼠标输入,只会触发Mouse冒泡隧道事件;
2.触笔输入,会触发除了Stylus事件外,还会触发Mouse事件;
3.触摸输入,触发Touch事件、Stylus事件、Mouse事件。
如何区分三类事件可以参考 WPF 屏幕点击的设备范例 - 唐宋元明清2188 - 博客园,封装全部事件范例(包括Button阻止冒泡事件场景)整合成一个Device事件可以参考 WPF 设备输入事件封装 - 唐宋元明清2188 - 博客园
和小搭档在定位PPT讲明翻页问题时,发现在以WIN32跨进程设置父子窗口后再调动PPT上下翻页,讲明触摸操纵只会触发Mouse事件,但此Mouse事件只有Down没有Up,这类触摸只转鼠标的场景后面我单独描述下。当我尝试使用鼠标+触摸混合操纵时,也能复现Mouse没有Up抬起事件。
鼠标+触摸,复现步骤:
1.鼠标按下
2.在其它位置触摸按下
3.鼠标抬起
4.触摸抬起
我们看看WPF真实反馈的事件输出,UI监听下面几个冒泡事件:- 1 <Grid Background="LightGray"
- 2 MouseDown="UIElement_OnMouseDown" MouseUp="UIElement_OnMouseUp"
- 3 StylusDown="UIElement_OnStylusDown" StylusUp="UIElement_OnStylusUp"
- 4 TouchDown="UIElement_OnTouchDown" TouchUp="UIElement_OnTouchUp">
- 5 </Grid>
复制代码 记载下输出事件,下面区分了鼠标、触摸、触笔:- 1 private void UIElement_OnMouseDown(object sender, MouseButtonEventArgs e)
- 2 {
- 3 if (e.StylusDevice != null) return;
- 4 Debug.WriteLine("UIElement_OnMouseDown");
- 5 }
- 6 private void UIElement_OnMouseUp(object sender, MouseButtonEventArgs e)
- 7 {
- 8 if (e.StylusDevice != null) return;
- 9 Debug.WriteLine("UIElement_OnMouseUp");
- 10 }
- 11
- 12 private void UIElement_OnStylusDown(object sender, StylusDownEventArgs e)
- 13 {
- 14 if (e.StylusDevice.TabletDevice.Type != TabletDeviceType.Stylus)
- 15 {
- 16 return;
- 17 }
- 18 Debug.WriteLine("UIElement_OnStylusDown");
- 19 }
- 20 private void UIElement_OnStylusUp(object sender, StylusEventArgs e)
- 21 {
- 22 if (e.StylusDevice.TabletDevice.Type != TabletDeviceType.Stylus)
- 23 {
- 24 return;
- 25 }
- 26 Debug.WriteLine("UIElement_OnStylusUp");
- 27 }
- 28
- 29 private void UIElement_OnTouchDown(object? sender, TouchEventArgs e)
- 30 {
- 31 Debug.WriteLine("UIElement_OnTouchDown");
- 32 }
- 33 private void UIElement_OnTouchUp(object? sender, TouchEventArgs e)
- 34 {
- 35 Debug.WriteLine("UIElement_OnTouchUp");
- 36 }
复制代码 输出效果如下,鼠标+触摸混合操纵时MouseUp事件被吞了:
我们用Snoop抓事件列表,Grid层鼠标按下后就没有后续了:
有意思的是,鼠标重新按下抬起时,是有正常的MouseDown、MouseUp事件触发,所以只是之前那一次MouseUp未触发:
然后找了台Surface,使用鼠标+触笔按上面路径验证,也是有同样问题:
但是我发现使用触摸板+触笔,MouseUp事件正常触发了。。。
所以这WPF框架问题,还区分鼠标、触摸板?我们看TouchPad设备的原理:标识输入设备 - Windows apps | Microsoft Learn、触控板交互 - Windows apps | Microsoft Learn,触摸板可以实现鼠标+多点触摸的功能,但单指操纵时并不是鼠标或者触摸,如果要区分的话就必要通过其它其它途径。好比这篇文章有说相比正常的鼠标操纵,触摸板返回鼠标消息时GetMessageExtraInfo()函数返回值是0: 如何区分触摸板和鼠标设备生成的WM_MOUSE***消息?-腾讯云开发者社区-腾讯云
这个问题目前没有解决方案,上面跨进程设置父子窗口导致鼠标失效的问题,可以在触摸事件输入后判定上一次操纵是否为鼠标事件,然后手动触发相应鼠标抬起事件的业务逻辑。另外同一控件多设备混合输入场景比力少见,白板、讲明等应用可能使用到,也可以同样修复补偿下,或者在设备输入事件封装内处理 WPF 设备输入事件封装 - 唐宋元明清2188 - 博客园
出处:http://www.cnblogs.com/kybs0/让学习成为习惯,假设来日诰日就有巨大机遇等着你,你准备好了么本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |