WPF触屏Touch事件在嵌套控件中的响应问题

简介: 原文:WPF触屏Touch事件在嵌套控件中的响应问题前几天遇到个touch事件的坑,记录下来以增强理解。 具体是 想把一个listview嵌套到另一个listview,这时候如果list view(子listview)的内容过多超过容器高度,它是不会出现滚动条压缩内容区域的,反而会将滚动区域转移到外面的list view(父listview),这个无可争议,但这个问题开始没留意,为待会的坑埋下伏笔。
原文: WPF触屏Touch事件在嵌套控件中的响应问题

前几天遇到个touch事件的坑,记录下来以增强理解。

具体是 想把一个listview嵌套到另一个listview,这时候如果list view(子listview)的内容过多超过容器高度,它是不会出现滚动条压缩内容区域的,反而会将滚动区域转移到外面的list view(父listview),这个无可争议,但这个问题开始没留意,为待会的坑埋下伏笔。委屈

因为 然后就是设置鼠标滚轮。

首先我使用了MouseWheel事件,奇怪的是它明明是个路由事件,然而listview似乎做了处理,没有冒泡到父级。

于是我改写PreviewMouseWheel事件,吧从父级传过来的时间再冒泡回去。

在子类的listview中,我在滚动事件里写了个向上传递的触发事件:

 
 private void BodyList_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
        {
            var eventArg = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta);
            eventArg.RoutedEvent = UIElement.MouseWheelEvent;
            eventArg.Source = sender;
            BodyList.RaiseEvent(eventArg);
        }

 

这样我就能实现当鼠标焦点在子listview时,能触发父级的滚动事件

这时候为了触摸屏操作,我如是写了touchdown .touchmove touchup 三个事件,可是,当手势在子listview做滑动操作的时候,父级不滑动。

即使我完全伪造一个source为上级的touch事件,父级仍然岿然不动,如图:

      private void UIElement_OnTouchMove(object sender, TouchEventArgs e)
        {
            
            var eventArg = new TouchEventArgs(e.TouchDevice,e.Timestamp);
            eventArg.RoutedEvent = UIElement.TouchMoveEvent;
            eventArg.Source = HAHAListBox;
            (sender as UIElement).TryFindParent<ListBox>().RaiseEvent(e);
            e.Handled = true;
        }

 

 

 

于是我开始找原因,touch事件同样是路由事件,于MouseWheel不同的是,我可以在父listview触发它。

那么是什么原因呢,通过可视化树工具,可以发现,在嵌套的listview中实际上嵌套了两个scrollview, 当touch事件在 子listview中触发时,实际上事件被子级中的scrollview吸收了。但是为何伪造后仍然无法反应?

那是由于touch事件是一个特殊的事件,至少有别于滚轮事件,控件需要对手势在触摸屏上的坐标做出响应,两个相互嵌套的滑动控件,无法对同一手势坐标做出反应,否则他们之间的相对位置就会发生改变,也就是说两个scrollview不能同时依赖一个手势源,只有最上层的scrollview才能响应目标源。

不知道微软为何这么设定,至少我的理解是这样的

由于开始的设置,子listview中的scrollview永远不会有效果。因此容易被忽略

所以我们只要重写底层listview的template就好了,把原来包裹ItemsPresenter的Scrollview控件给删掉

touch事件就能被父一级的listview触发了!

 

希望这个绕坑的经历能帮助到大家,谢谢!

目录
相关文章
|
6月前
|
C# 开发者 Windows
基于Material Design风格开源、易用、强大的WPF UI控件库
基于Material Design风格开源、易用、强大的WPF UI控件库
384 0
|
6月前
|
C#
浅谈WPF之装饰器实现控件锚点
使用过visio的都知道,在绘制流程图时,当选择或鼠标移动到控件时,都会在控件的四周出现锚点,以便于修改大小,移动位置,或连接线等,那此功能是如何实现的呢?在WPF开发中,想要在控件四周实现锚点,可以通过装饰器来实现,今天通过一个简单的小例子,简述如何在WPF开发中,应用装饰器,仅供学习分享使用,如有不足之处,还请指正。
138 1
|
3月前
|
开发框架 缓存 前端开发
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(11) -- 下拉列表的数据绑定以及自定义系统字典列表控件
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(11) -- 下拉列表的数据绑定以及自定义系统字典列表控件
|
3月前
|
C# 开发者 Windows
一款基于Fluent设计风格、现代化的WPF UI控件库
一款基于Fluent设计风格、现代化的WPF UI控件库
|
3月前
|
C# Windows
WPF中如何使用HandyCotrol控件库
WPF中如何使用HandyCotrol控件库
190 1
|
3月前
|
C# 微服务 Windows
模块化革命:揭秘WPF与微服务架构的完美融合——从单一职责原则到事件聚合器模式,构建高度解耦与可扩展的应用程序
【8月更文挑战第31天】本文探讨了如何在Windows Presentation Foundation(WPF)应用中借鉴微服务架构思想,实现模块化设计。通过将WPF应用分解为独立的功能模块,并利用事件聚合器实现模块间解耦通信,可以有效提升开发效率和系统可维护性。文中还提供了具体示例代码,展示了如何使用事件聚合器进行模块间通信,以及如何利用依赖注入进一步提高模块解耦程度。此方法不仅有助于简化复杂度,还能使应用更加灵活易扩展。
99 0
|
3月前
|
C# 前端开发 UED
WPF数据验证实战:内置控件与自定义规则,带你玩转前端数据验证,让你的应用程序更上一层楼!
【8月更文挑战第31天】在WPF应用开发中,数据验证是确保输入正确性的关键环节。前端验证能及时发现错误,提升用户体验和程序可靠性。本文对比了几种常用的WPF数据验证方法,并通过示例展示了如何使用内置验证控件(如`TextBox`)及自定义验证规则实现有效验证。内置控件结合`Validation`类可快速实现简单验证;自定义规则则提供了更灵活的复杂逻辑支持。希望本文能帮助开发者更好地进行WPF数据验证。
109 0
|
3月前
|
C# UED 定位技术
WPF控件大全:初学者必读,掌握控件使用技巧,让你的应用程序更上一层楼!
【8月更文挑战第31天】在WPF应用程序开发中,控件是实现用户界面交互的关键元素。WPF提供了丰富的控件库,包括基础控件(如`Button`、`TextBox`)、布局控件(如`StackPanel`、`Grid`)、数据绑定控件(如`ListBox`、`DataGrid`)等。本文将介绍这些控件的基本分类及使用技巧,并通过示例代码展示如何在项目中应用。合理选择控件并利用布局控件和数据绑定功能,可以提升用户体验和程序性能。
66 0
|
3月前
|
开发框架 前端开发 JavaScript
WPF应用开发之控件动态内容展示
WPF应用开发之控件动态内容展示
|
3月前
|
开发框架 前端开发 JavaScript
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(3)--自定义用户控件
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(3)--自定义用户控件