2019-11-29-WPF-模拟触摸设备
| title | author | date | CreateTime | categories |
|---|---|---|---|---|
|
WPF 模拟触摸设备
|
lindexi
|
2019-11-29 08:47:53 +0800
|
2019-5-11 17:2:6 +0800
|
WPF
|
在 WPF 中触摸只是框架的一层,可以通过代码模拟触摸
创建一个类继承 TouchDevice 然后重写 GetTouchPoint 和 GetIntermediateTouchPoints 方法,可以在这个类里面通过调用 ReportDown 等方法模拟触摸的按下和移动
最简单的实现请看下面代码
public class BurnerkadelWallnadarli : TouchDevice
{
/// <inheritdoc />
public BurnerkadelWallnadarli(int deviceId, Window window) : base(deviceId)
{
Window = window;
} /// <summary>
/// 触摸点
/// </summary>
public Point Position { set; get; } /// <summary>
/// 触摸大小
/// </summary>
public Size Size { set; get; } public void Down()
{
TouchAction = TouchAction.Down; if (!IsActive)
{
SetActiveSource(PresentationSource.FromVisual(Window)); Activate();
ReportDown();
}
else
{
ReportDown();
}
} public void Move()
{
TouchAction = TouchAction.Move; ReportMove();
} public void Up()
{
TouchAction = TouchAction.Up; ReportUp();
Deactivate();
} private Window Window { get; } private TouchAction TouchAction { set; get; } /// <inheritdoc />
public override TouchPoint GetTouchPoint(IInputElement relativeTo)
{
return new TouchPoint(this, Position, new Rect(Position, Size), TouchAction);
} /// <inheritdoc />
public override TouchPointCollection GetIntermediateTouchPoints(IInputElement relativeTo)
{
return new TouchPointCollection()
{
GetTouchPoint(relativeTo)
};
}
}
在 TouchDevice 里面,调用触摸按下和移动等的方法是没有传入参数的,在框架是通过 GetTouchPoint 拿到当前用户触摸的点
在按下的时候需要激活,激活的时候需要传入一个 PresentationSource 在框架通过这个值进行命中测试找到触摸按下的点是按到哪个元素
使用的时候只需要创建 BurnerkadelWallnadarli 然后调用对应的按下移动等方法就可以了,因为在构造的时候传入了窗口,所以在按下等事件可以通过传入的窗口进行命中测试找到按下的元素,从元素触发路由事件
大概的调用顺序是这样的,在触摸的第一个事件是按下,在按下的时候使用下面代码
SetActiveSource(PresentationSource.FromVisual(Window)); Activate();
ReportDown();
在 SetActiveSource 会将传入的 PresentationSource 设置在本地的字段 _activeSource 这样可以在拿到点的时候调用
在调用 Activate 方法会调用一次 UpdateDirectlyOver 这个方法调用 GetTouchPoint 传入一个空参数,用来判断当前是否命中到元素,一般都是没有命中的,需要到 ReportDown 的时候才可能命中元素。在 Activate 会将当前的 TouchDevice 加入到 TouchDevice._activeDevices 这个静态字段里面,如果刚好这时的静态字段只有一个元素,那么就设置当前的触摸设备是主触摸设备
设置触摸设备是主触摸设备是因为在触摸的时候如果用户是多个手指触摸,一个手指对应一个触摸设备,所以第一个手指对应主触摸设备
调用 ReportDown 会先设置本地字段 _isDown 为 true 然后调用 UpdateDirectlyOver 方法更新当前按下点到的元素,然后调用 RaiseTouchDown 方法在当前点到的元素触摸触摸按下的路由事件,可以看到此时的路由事件是不需要再获取当前的触摸点,因为只是在点到的元素触摸事件,如果这个元素需要知道当前的触摸点,只需要在方法使用参数的 e.GetTouchPoint 方法就可以重新拿到触摸点。因为获取触摸点方法是可以重写的,所以第一次获取的用于命中测试的触摸点可以和元素收到触摸事件获取的触摸点返回不同的点
只需要拿到了对应的元素就可以在元素触发事件,从触摸到事件请看WPF 触摸到事件
调用 ReportMove 移动的方法也是差不多,首先通过 UpdateDirectlyOver 找到命中测试的元素,然后触发路由事件。如果元素不关注触摸点击的点就不需要再次调用获取触摸点方法
那么 UpdateDirectlyOver 是如何进行命中测试的?首先通过获取触摸点方法拿到传入空参数时的触摸点,这时相对的应该是窗口的坐标。通过 TouchDevice.LocalHitTest 方法拿到命中测试的元素,在底层调用的是 MouseDevice.LocalHitTest 方法
所以可以通过上面定义的类模拟触摸,只需要创建出来,然后调用对应的方法就可以,如下面的代码就模拟了按下和移动
var burnerkadelWallnadarli = new BurnerkadelWallnadarli(1, this); await Task.Delay(1000);
burnerkadelWallnadarli.Down(); await Task.Delay(1000);
// 设置当前触摸点
burnerkadelWallnadarli.Move();
通过这个方法模拟触摸可以走原有的 WPF 触摸命中测试,也能走路由事件
关于 WPF 的触摸到事件请看 WPF 触摸到事件
本文用到的代码放在 github
2019-11-29-WPF-模拟触摸设备的更多相关文章
- 2019/11/12 CSP模拟赛&&考前小总结
写在前面的总结 离联赛只有几天了,也马上就要回归文化课了. 有点舍不得,感觉自己的水平刚刚有点起色,却又要被抓回文化课教室了,真想在机房再赖几天啊. 像19/11/11那场的简单题,自己还是能敲出一些 ...
- 2019.7.29 NOIP模拟测试10 反思总结【T2补全】
这次意外考得不错…但是并没有太多厉害的地方,因为我只是打满了暴力[还没去推T3] 第一题折腾了一个小时,看了看时间先去写第二题了.第二题尝试了半天还是只写了三十分的暴力,然后看到第三题是期望,本能排斥 ...
- 2019.11.29 Mysql的数据操作
为名为name的表增加数据(插入所有字段) insert into name values(1,‘张三’,‘男’,20); 为名为name的表增加数据(插入部分字段) insert into name ...
- 2019.11.29 SAP SMTP郵件服務器配置 發送端 QQ郵箱
今天群裏的小夥伴問了如何配置郵件的問題,隨自己在sap裏面配置了一個 1. RZ10配置參數 a) 参数配置前,先导入激活版本 执行完毕后返回 b) 输入参数文件DEFAU ...
- 2019/11/8 CSP模拟
T1 药品实验 内网#4803 由概率定义,有\[a + b + c = 0\] 变形得到\[1 - b = a + c\] 根据题意有\[p_i = a p _{i - 1} + b p_i + c ...
- 2019/11/1 CSP模拟
写在前面的反思 该拿的部分分还是得拿完啊,因为懒+动作慢没有写最后一道题的菊花图和链的情况,其实这两个点并不难.. 虽然只有\(10pts\),但是已经足够往上爬一截了啊,额外的\(10pts\)在今 ...
- 2019.10.29 csp-s模拟测试93 反思总结
T1: 求出前缀和,三维偏序O(nlog2n)CDQ 二维其实就可以 #include<iostream> #include<cstdio> #include<cstri ...
- 2019.10.29 csp-s模拟测试92 反思总结
今天快乐的墨雨笙因为什么而几乎爆零了呢? 顾此失彼+不会对拍+无脑的复杂度 今天高兴的墨雨笙又因为什么调了一个下午呢? 不明题意+不想范围+板子低级错误 R.I.P. T1: //唉 //害怕TLE, ...
- 2019.9.29 csp-s模拟测试55 反思总结
不咕咕咕是一种美德[大雾] 头一次体会到爆肝写题解??? 这次考试我们没赶上,是后来掐着时间每个人自己考的.我最后的分数能拿到152…熟悉的一题AC两题爆炸. 强烈吐槽出题人起名走心 T1联: 发现每 ...
- pycharm+anaconda在Mac上的配置方法 2019.11.29
内心os: 听人说,写blog是加分项,那他就不是浪费时间的事儿了呗 毕竟自己菜还是留下来东西来自己欣赏吧 Mac小电脑上进行python数据开发环境的配置 首先下载Anaconda,一个超好用的数据 ...
随机推荐
- Visual Studio模板代码注释小技巧
在日常开发过程中,难免有这样一种需求:就是你所建的每一个类文件或者接口文件都需要标注下作者姓名以及类的用途.如果我们每次创建文件的时候都需要写一遍这些信息是很烦神的.还好Visual Studio给我 ...
- 最近的项目系之2——core3.0整合Autofac
1.前言 core3.0与之前版本相比,有一些brokenchanges,那周边一些配套组件往往也难逃brokenchanges,Autofac也不例外.这里重点关注core整合Autofac,与之前 ...
- CSS渐变的两种基本用法
1.线性渐变(linear-gradient) 基础用法:background:linear-gradient(angle,start-color,soft-line,end-color); 依次解释 ...
- swift(四)swift的广义匹配
//swift的广义匹配 let x = switch x { ...: println("个位数") ...: println("十位数") default: ...
- emmet的用法
emmet 是一个提高前端开发效率的一个工具.emmet允许在html.xml.和css等文档中输入缩写,然后按tab键自动展开为完整的代码片段. 一.Sublime Text 3 安装插件Emmet ...
- js对象属性方法
window对象方法方法: 1.alert():显示带有一段消息和确认按钮的警告框 2.prompt():显示可提示用户输入的对话框 3.fonfirm():显示带有一段消息以及确认按钮和取消按钮的对 ...
- oracle自定义存储过程:删除表(无论表是否存在)和检测表是否存在
oracle删除表,如果表不存在,就报错,在跑大型脚本(脚本长且耗时的时候)比较麻烦,一般希望的是点开始然后脚本运行到结束,不可能一直盯着屏幕等弹出提示手工点掉,mysql就很好有drop table ...
- JAVA框架中XML文件
其实在JAVA开发中servlet配置,映射注入配置等等都可以用xml来配置 在此处的department是实体类的名字,而不是对应的数据库表的名字 数据库表的字段名=#{实体类属性名} 逆向工程生成 ...
- client-go向controller进发---code-generator实现
这个时间长了,可能前后想了一周时间. 哎,其它不怪,只怪go的工程包管理这几年太混乱, 而国内下载资源也太漫长. 现在,只能坚持 使用go mod了. 但在使用code-generator时,go m ...
- 10.Java基础_IDEA的使用
IDEA下项目结构: 项目->模块->包->java文件 流程图 1.创建一个空项目(JavaSE_Code) 选择Empty Project 输入项目名和路径 2.创建一个新模块 ...