原文: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-模拟触摸设备的更多相关文章

  1. 2019/11/12 CSP模拟赛&&考前小总结

    写在前面的总结 离联赛只有几天了,也马上就要回归文化课了. 有点舍不得,感觉自己的水平刚刚有点起色,却又要被抓回文化课教室了,真想在机房再赖几天啊. 像19/11/11那场的简单题,自己还是能敲出一些 ...

  2. 2019.7.29 NOIP模拟测试10 反思总结【T2补全】

    这次意外考得不错…但是并没有太多厉害的地方,因为我只是打满了暴力[还没去推T3] 第一题折腾了一个小时,看了看时间先去写第二题了.第二题尝试了半天还是只写了三十分的暴力,然后看到第三题是期望,本能排斥 ...

  3. 2019.11.29 Mysql的数据操作

    为名为name的表增加数据(插入所有字段) insert into name values(1,‘张三’,‘男’,20); 为名为name的表增加数据(插入部分字段) insert into name ...

  4. 2019.11.29 SAP SMTP郵件服務器配置 發送端 QQ郵箱

    今天群裏的小夥伴問了如何配置郵件的問題,隨自己在sap裏面配置了一個 1.    RZ10配置參數 a)       参数配置前,先导入激活版本 执行完毕后返回 b)      输入参数文件DEFAU ...

  5. 2019/11/8 CSP模拟

    T1 药品实验 内网#4803 由概率定义,有\[a + b + c = 0\] 变形得到\[1 - b = a + c\] 根据题意有\[p_i = a p _{i - 1} + b p_i + c ...

  6. 2019/11/1 CSP模拟

    写在前面的反思 该拿的部分分还是得拿完啊,因为懒+动作慢没有写最后一道题的菊花图和链的情况,其实这两个点并不难.. 虽然只有\(10pts\),但是已经足够往上爬一截了啊,额外的\(10pts\)在今 ...

  7. 2019.10.29 csp-s模拟测试93 反思总结

    T1: 求出前缀和,三维偏序O(nlog2n)CDQ 二维其实就可以 #include<iostream> #include<cstdio> #include<cstri ...

  8. 2019.10.29 csp-s模拟测试92 反思总结

    今天快乐的墨雨笙因为什么而几乎爆零了呢? 顾此失彼+不会对拍+无脑的复杂度 今天高兴的墨雨笙又因为什么调了一个下午呢? 不明题意+不想范围+板子低级错误 R.I.P. T1: //唉 //害怕TLE, ...

  9. 2019.9.29 csp-s模拟测试55 反思总结

    不咕咕咕是一种美德[大雾] 头一次体会到爆肝写题解??? 这次考试我们没赶上,是后来掐着时间每个人自己考的.我最后的分数能拿到152…熟悉的一题AC两题爆炸. 强烈吐槽出题人起名走心 T1联: 发现每 ...

  10. pycharm+anaconda在Mac上的配置方法 2019.11.29

    内心os: 听人说,写blog是加分项,那他就不是浪费时间的事儿了呗 毕竟自己菜还是留下来东西来自己欣赏吧 Mac小电脑上进行python数据开发环境的配置 首先下载Anaconda,一个超好用的数据 ...

随机推荐

  1. PDF目录编辑器使用介绍

    PDF目录编辑器使用介绍 魏刘宏 2019.06.28 PDF 是一个比较优秀的文档格式,能够保证在任何终端显示的样式是一样的.但同时也带来了一个问题,就是编辑不方便,其实这也是这个格式特意为之的,无 ...

  2. 备战双十一,腾讯WeTest有高招——小程序质量优化必读

    WeTest 导读 2018年双十一战场小程序购物通道表现不俗,已逐渐成为各大品牌方角逐的新战场.数据显示,截止目前95%的电商平台都已经上线了小程序.除了电商企业外,许多传统线下商家也开始重视小程序 ...

  3. Window常用且通用快捷键

    Ctrl系列: Ctrl +z :回撤,后退 Ctrl +a :全选 Alt系列: Alt+Tab :切换窗口 Window系列 Window+R:打开“运行”窗口 Window+D:显示桌面 其中常 ...

  4. Git:SSH、SSH与HTTP区别、git常用命令

    SSH1.首先需要检查你电脑是否已经有 SSH key cd ~/.sshls12.ssh表示ssh文件是个隐藏文件查看是否存在 id_rsa.pub 或 id_dsa.pub 文件,如果文件已经存在 ...

  5. PHP代码篇(三)--常用方法

    模块下不间断更新,PHP常用方法,欢迎留言! 一.递归删除指定目录下所有文件及文件夹 /** * 递归删除指定目录下所有文件及文件夹 * @param unknown $path,删除路径 */ fu ...

  6. js实现textarea自适应高度

    html结构: <div class="container" id="container"> <div class="text-wr ...

  7. Windows 跟 Linux 文件共享:Samba 设置

    用 Samba  服务器 https://my.oschina.net/u/3783115/blog/1919892?from=timeline https://blog.51cto.com/1372 ...

  8. 自动化部署-svn hook触发构建

    目的 之前是通过轮询的形式,2分钟更新一次svn,即时性不高,现在想要实现提交代码时直接触发构建 方案 使用svn的服务器hook,当有代码提交时请求jenkins api实现构建 具体实现 1.je ...

  9. 在python的虚拟环境venv中使用gunicorn

    昨天遇到的问题,一个服务器上有好几个虚拟机环境. 我active进一个虚拟环境,安装了新的三方库之后, 使用gunicorn启动django服务, 但还是死活提示没有安装这个三方库. 一开始没有找到原 ...

  10. 浅谈JS递归

    简单理解就是函数内部不断调用自身 直接上代码: function dg(num){ ){ ; }else{ ) } } console.log(dg()) 最后输出值为21,记住加限制条件退出递归,不 ...