当前位置: 首页 > news >正文

WPF异步UI交互功能的实现方法

前面的文章我们提及过,异步UI的基础实现。基本思路主要是开启新的UI线程,并通过VisualTarget将UI线程上的Visual(即RootVisual)连接到主线程上的UI上即可渲染显示。

但是,之前的实现访问是没有交互能力的,视觉树上的UI并不能实现鼠标事件。那么今天我们就把交互的工作也给完成了。

实现交互能力的核心在于PresentationSource,它是完成交互功能的核心。它提供了交互源,它是一个抽象类,不能直接使用。我们需要通过继承它来实现交互逻辑。

具体代码如下:

 public class VisualTargetPresentationSource : PresentationSource{public VisualTargetPresentationSource(HostVisual hostVisual){_visualTarget = new VisualTarget(hostVisual);}public override Visual RootVisual{get{return _visualTarget.RootVisual;}set{Visual oldRoot = _visualTarget.RootVisual;_visualTarget.RootVisual = value;//此处是关键代码,通过根的时间通知,触发Load事件。通知视觉树,元素已经加载。//元素加载后,IsVisible会变成True,命中测试才能开始工作RootChanged(oldRoot, value);}}public override bool IsDisposed{get{return false;}}protected override CompositionTarget GetCompositionTargetCore(){return _visualTarget;}private VisualTarget _visualTarget;}

有了上述代码,我们的异步UI具备了交互能力。但是此时,我们用鼠标点击元素,依然是不会有动作发生的。

因为我们的UI是在异步线程上,它的功能受到一定的阉割,它并不能直接响应鼠标或者键盘事件。所以我们需要通过VisualHost来做路由事件的传递。

请看完整的示例:

//异步UI容器public class AsyncUIContainer : UIElement{public AsyncUIContainer(){Initialize();}private HostVisual hostVisual;private Grid RootVisual;private DispatcherUIThread dispatcherUIThread;/// <summary>/// /// </summary>private void Initialize(){hostVisual = new HostVisual();dispatcherUIThread = new DispatcherUIThread();dispatcherUIThread.Start();dispatcherUIThread.Dispatcher.Invoke(() =>{RootVisual = new Grid();new VisualTargetPresentationSource(hostVisual){RootVisual = RootVisual};});AddVisualChild(hostVisual);}public void UpdateRootLayout(Action<Grid> action){if (action != null){RootVisual.Dispatcher.Invoke(() =>{action(RootVisual);});}}#region overrideprivate UIElement _hitElement;protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters){RootVisual.Dispatcher.Invoke(() =>{_hitElement = (UIElement)RootVisual.InputHitTest(hitTestParameters.HitPoint);});if (_hitElement != null){return new PointHitTestResult(this, hitTestParameters.HitPoint);}else{return null;}}//此处是用来做路由事件转发,用于触发UI线程上的元素事件protected override void OnMouseDown(MouseButtonEventArgs e){base.OnMouseDown(e);if (_hitElement != null){_hitElement.Dispatcher.Invoke(() => _hitElement.RaiseEvent(e));}}//重写布局系统,让多线程UI元素能正常布局protected override Size MeasureCore(Size availableSize){if (availableSize.Height > 0 && availableSize.Width > 0 && !(double.IsInfinity(availableSize.Height) || double.IsInfinity(availableSize.Width))){RootVisual.Dispatcher.Invoke(() =>{RootVisual.Measure(availableSize);});return availableSize;}else{var minSize = new Size(200, 200);RootVisual.Dispatcher.Invoke(() =>{RootVisual.Measure(minSize);                  });return minSize;}}//重写布局系统,让多线程UI元素能正常布局protected override void ArrangeCore(Rect finalRect){base.ArrangeCore(finalRect);RootVisual.Dispatcher.Invoke(() =>{RootVisual.Arrange(finalRect);});RenderSize = finalRect.Size;}//指定起Visual的数量protected override int VisualChildrenCount => 1;//指定需要渲染的Visual对象protected override Visual GetVisualChild(int index){return hostVisual;}public void Dispose(){dispatcherUIThread?.Dispose();}#endregionpublic class VisualTargetPresentationSource : PresentationSource{public VisualTargetPresentationSource(HostVisual hostVisual){_visualTarget = new VisualTarget(hostVisual);}public override Visual RootVisual{get{return _visualTarget.RootVisual;}set{Visual oldRoot = _visualTarget.RootVisual;_visualTarget.RootVisual = value;RootChanged(oldRoot, value);}}public override bool IsDisposed{get{return false;}}protected override CompositionTarget GetCompositionTargetCore(){return _visualTarget;}private VisualTarget _visualTarget;}}

到这里,你就可以愉快的玩耍了。下期我们再实现异步UI在XAML上的编辑能力,可以在xaml中添加普通的xaml代码一样简单使用。

相关文章:

WPF异步UI交互功能的实现方法

前面的文章我们提及过&#xff0c;异步UI的基础实现。基本思路主要是开启新的UI线程&#xff0c;并通过VisualTarget将UI线程上的Visual(即RootVisual)连接到主线程上的UI上即可渲染显示。 但是&#xff0c;之前的实现访问是没有交互能力的&#xff0c;视觉树上的UI并不能实现…...

网络基础 - 地址篇

一、IP 地址 IP 协议有两个版本&#xff0c;IPv4 和 IPv6IP 地址(IPv4 地址)是一个 4 字节&#xff0c;32 位的正整数&#xff0c;通常使用 “点分十进制” 的字符串进行表示&#xff0c;例如 192.168.0.1&#xff0c;用点分割的每一个数字表示一个字节&#xff0c;范围是 0 ~…...

# [Unity] 【游戏开发】Unity开发基础2-Unity脚本编程基础详解

Unity脚本编程是创建互动式游戏体验的核心技能之一。本文将详细讲解Unity脚本编程的基础知识,包括变量和数据类型、程序逻辑、方法等方面,并通过实例展示如何使用这些基本知识完成简单功能的实现。 1. 新建Unity脚本的基本结构 当在Unity中创建一个脚本时,Unity会生成如下基…...

Milvus实操

概念 Milvus 关键概念优化笔记 Milvus 是一个高性能、可扩展的开源向量数据库&#xff0c;专为处理海量向量数据和执行相似性搜索而设计。以下是 Milvus 中的一些核心概念及其详细解释。 1. 集合&#xff08;Collection&#xff09; 定义&#xff1a; 集合是 Milvus 中存储向…...

35 基于单片机的精确电压表DA-AD转换

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于51单片机&#xff0c;采用DAC0832和ADC0832检测电压&#xff0c;0到8.5V&#xff0c;设计复位电路 LED管显示实际稳压值&#xff0c;初始电压0 二、硬件资源 基于KEIL5编写C代码&#xff0c…...

JDBC 设置 PostgreSQL 查询中 any(?) 的参数

这段时间都纠缠于 Java 如何操作 PostgreSQL 数据库上&#xff0c;千方百计的为求得更好的性能。为此我们用上了 Batch, 或用 id any(?) 这种更 PostgreSQL 化的数组参数操作。其实它还有更多数组方面的花样可以玩&#xff0c;毕竟 PostgreSQL 数据库有一种广纳百川的胸怀&am…...

【11-20期】Java面试进阶:深入解析核心问题与实战案例

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;Java &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; 文章题目&#xff1a;Java面试进阶&#xff1a;深入解析11-20期核心问题与实战案例 摘要&#xff1a; 本篇…...

C++——内存池_2

C内存池 重载 new 和 delete 运算符C内存池使用内存池的目的逐步实现内存池 重载 new 和 delete 运算符 实际开发中&#xff0c;重载new和delete的主要目的是实现内存池。内存池在高性能的服务程序中很常用。点击浏览重载 new 和 delete 运算符的内容&#xff0c;建议先看这部…...

如何使用PHP爬虫获取店铺详情:一篇详尽指南

在数字化时代&#xff0c;数据的价值不言而喻。对于企业来说&#xff0c;获取竞争对手的店铺详情、顾客评价等信息对于市场分析和决策至关重要。PHP作为一种广泛使用的服务器端脚本语言&#xff0c;结合其强大的库支持&#xff0c;使得编写爬虫程序变得简单而高效。本文将详细介…...

HTML5和CSS3新增特性

HTML5的新特性 HTML5新增的语义化标签 HTML5 的新增特性主要是针对于以前的不足&#xff0c;增加了一些新的标签、新的表单和新的表单属性等。 这些新特性都有兼容性问题&#xff0c;基本是 IE9 以上版本的浏览器才支持&#xff0c;如果不考虑兼容性问题&#xff0c;可以大量…...

linux运行vue编译后的项目

如果你的 Vue 项目使用了 history 模式&#xff08;而非默认的 hash 模式&#xff09;&#xff0c;在纯静态服务器中会出现类似的问题。因为 Vue Router 的 history 模式要求所有未匹配的路径都重定向到 index.html&#xff0c;以便 Vue 前端处理路径。 首先在本地执行npm run…...

论文阅读:A Software Platform for Manipulating theCamera Imaging Pipeline

论文代码开源链接&#xff1a; A Software Platform for Manipulating the Camera Imaging Pipelinehttps://karaimer.github.io/camera-pipeline/摘要&#xff1a;论文提出了一个Pipline软件平台&#xff0c;可以方便地访问相机成像Pipline的每个阶段。该软件允许修改单个模块…...

【MySQL篇】持久化和非持久化统计信息的深度剖析(第一篇,总共六篇)

&#x1f4ab;《博主介绍》&#xff1a;✨又是一天没白过&#xff0c;我是奈斯&#xff0c;DBA一名✨ &#x1f4ab;《擅长领域》&#xff1a;✌️擅长Oracle、MySQL、SQLserver、阿里云AnalyticDB for MySQL(分布式数据仓库)、Linux&#xff0c;也在扩展大数据方向的知识面✌️…...

Ubuntu下安装Qt

1.如图1所示&#xff0c;在Index of /archive上下载安装包&#xff1b; 图1 2.将图1安装包下载好之后&#xff0c;通过共享文件夹的方式拷贝到ubutntu&#xff0c;如图2所示&#xff1b; 图2 3.如图3所示&#xff0c;执行chmod x qt-creator-opensource-linux-x86_64-10.0.2.…...

丹摩征文活动 | AI创新之路,DAMODEL助你一臂之力GPU

目录 前言—— DAMODEL&#xff08;丹摩智算&#xff09; 算力服务 直观的感受算力提供商的强大​ 平台功能介绍​ 镜像选择 云磁盘创建 总结 前言—— 只需轻点鼠标,开发者便可拥有属于自己的AI计算王国 - 从丰富的GPU实例选择,到高性能的云磁盘,再到预配置的深度学习…...

数据库(总结自小林coding)|索引失效的场景、慢查询、原因及如何优化?undo log、redo log、binlog 作用、MySQL和Redis的区别

数据库&#xff08;总结自小林coding&#xff09;|索引失效的场景、慢查询、原因及如何优化&#xff1f;undo log、redo log、binlog 作用、MySQL和Redis的区别 说一下索引失效的场景&#xff1f;什么是慢查询&#xff1f;原因是什么&#xff1f;可以怎么优化&#xff1f;undo …...

Docker容器运行CentOS镜像,执行yum命令提示“Failed to set locale, defaulting to C.UTF-8”

最近对运维比较感兴趣&#xff0c;以前虽然对公司负责的项目做过运维工作&#xff0c;但用的都是最原始的方法&#xff0c;例如是在阿里云服务器上直接安装jdk&#xff0c;tomcat,redis ,nginx 。这种方式对不大的项目还能够支持&#xff0c;随着项目变大&#xff0c;服务增加&…...

OpenCV基本图像处理操作(六)——直方图与模版匹配

直方图 cv2.calcHist(images,channels,mask,histSize,ranges) images: 原图像图像格式为 uint8 或 float32。当传入函数时应 用中括号 [] 括来例如[img]channels: 同样用中括号括来它会告函数我们统幅图 像的直方图。如果入图像是灰度图它的值就是 [0]如果是彩色图像 的传入的…...

【LLM学习笔记】第四篇:模型压缩方法——量化、剪枝、蒸馏、分解

文章目录 1. 为什么要进行模型压缩2. 模型量化2.1 常见数据类型2.2 浮点数表示2.3 线性量化2.4 非线性量化2.5 挑战2.6 实际应用 3. 模型剪枝4. 模型蒸馏4.1 模型蒸馏的基本流程4.2 模型蒸馏的优势4.3 实际应用 5. 低秩分解&#xff08;低秩近似&#xff09;5.1 基本概念5.2 实…...

python3 自动更新的缓存类

这个类会在后台自动更新缓存数据&#xff0c;你只需要调用方法来获取数据即可。 自动更新缓存类 以下是 AutoUpdatingCache 类的实现&#xff1a; import threading import timeclass AutoUpdatingCache:def __init__(self, update_function, expiry_time60):""&qu…...

英语知识网站开发:Spring Boot框架应用

3系统分析 3.1可行性分析 通过对本英语知识应用网站实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本英语知识应用网站采用SSM框架&#xff0c;JAVA作为开发语…...

文件上传upload-labs-docker通关

&#xff08;图片加载不出&#xff0c;说明被和谐了&#xff09; 项目一&#xff1a; sqlsec/ggctf-upload - Docker Image | Docker Hub 学习过程中,可以对照源码进行白盒分析. 补充&#xff1a;环境搭建在Linux虚拟机上的同时&#xff0c;以另一台Windows虚拟机进行测试最…...

git(Linux)

1.git 三板斧 基本准备工作&#xff1a; 把远端仓库拉拉取到本地了 .git --> 本地仓库 git在提交的时候&#xff0c;只会提交变化的部分 就可以在当前目录下新增代码了 test.c 并没有被仓库管理起来 怎么添加&#xff1f; 1.1 git add test.c 也不算完全添加到仓库里面&…...

Doris实战—构建日志存储与分析平台

构建日志存储与分析平台 日志是系统运行的详细记录,包含各种事件发生的主体、时间、位置、内容等关键信息。出于运维可观测、网络安全监控及业务分析等多重需求,企业通常需要将分散的日志采集起来,进行集中存储、查询和分析,以进一步从日志数据里挖掘出有价值的内容。 针…...

【vue3+Typescript】unapp+stompsj模式下替代plus-websocket的封装模块

由于plus-websocket实测存在消息丢失的问题&#xff0c;只能寻找替代的方案&#xff0c;看文章说使用原生的即可很好的工作。而目前在stompjs里需要使用websocket类型的封装模块&#xff0c;看了下原来提供的接口&#xff0c;采用uniapp原生的websocket模式&#xff0c;对原模块…...

Tcon技术和Tconless技术介绍

文章目录 TCON技术&#xff08;传统时序控制器&#xff09;定义&#xff1a;主要功能&#xff1a;优点&#xff1a;缺点&#xff1a; TCONless技术&#xff08;无独立时序控制器&#xff09;定义&#xff1a;工作原理&#xff1a;优点&#xff1a;缺点&#xff1a; TCON与TCONl…...

C#-利用反射自动绑定请求标志类和具体执行命令类

文章速览 概述例程请求类命名空间父类示例子类示例 命令类命名空间子类示例 记录的数据结构实现绑定方法 坚持记录实属不易&#xff0c;希望友善多金的码友能够随手点一个赞。 共同创建氛围更加良好的开发者社区&#xff01; 谢谢~ 概述 需求&#xff1a; 将指定的两种类型的…...

高中数学练习:初探均值换元法

文章目录 1. 均值换元法定义2. 均值换元法优点3. 均值换元法应用4. 均值换元法示例4.1 求解分式方程4.2 求解指数方程4.3 计算最大值 5. 实战小结 1. 均值换元法定义 均值换元法是一种数学技巧&#xff0c;通过引入新变量 t t t将两个变量 x x x和 y y y表示为它们的平均值加上…...

数据结构单链表,顺序表,广义表,多重链表,堆栈的学习

单链表 比如一个多项式&#xff0c;主要包括x的系数&#xff0c;x的指数&#xff0c;那么可以创建一个一维数组来存储它的系数和指数&#xff0c;用数组下标来表示。它的系数可以用数组下标对应的数组元素来储存。 可是这样储存会浪费空间所以采用单链表形式来存储。 即创建一…...

【保姆级教程】使用lora微调LLM并在truthfulQA数据集评估(Part 2.在truthfulQA上评估LLM)

上一期我们成功用lora微调了一个模型传送门&#xff0c;怎样评估模型呢&#xff1f;目前LLM没有一个统一的BENCHMARK。我们今天选用truthfulQA。 truthfulQA数据集格式如下所示 {question: What is the smallest country in the world that is at least one square mile in ar…...

济南模版网站/怎样交换友情链接

2019独角兽企业重金招聘Python工程师标准>>> 网关冗余与负载分担 读这篇文档之前&#xff0c;请读者先理清有关的专业术语和名词&#xff0c;尤其其中的同义词和并列词。 还要知道&#xff0c;人们之所以把计算机中的一些非常简单的逻辑复杂化&#xff0c;形成一个难…...

网站开发的学校/怎么打广告吸引客户

本来转载自http://blog.csdn.net/soulcq/article/details/5341561#comments。javaScript 中的 call() 是一个奇妙的方法&#xff0c;但也是一个让人迷惑的方法&#xff0c;先看一下官方的解释&#xff1a;call 方法请参阅应用于&#xff1a;Function 对象要求版本 5.5调用一个对…...

做网站的动态图片/苏州网站优化公司

文章目录一、循环语句1.1 for循环语句1.1.1 for语句的结构1.1.2 for语句应用示例1.2 while循环语句1.3 until循环语句1.3.1 until语句的结构二、 Shell函数2.1 Shell函数2.1 函数应用示例2.2 函数的作用范围2.3 函数的参数2.4 递归函数三、 Shell数组3.1 Shell数组3.2 Shell脚本…...

dw创建网站相册/怎么恶意点击对手竞价

QML (Qt Modeling Language) is a user interface markup language. It is a declarative language for designing user interface–centric applications....

网站建设怎样上传程序/怎么做一个公司网站

公众号关注 「奇妙的 Linux 世界」设为「星标」&#xff0c;每天带你玩转 Linux &#xff01;100 行代码可以干些什么&#xff1f;如果只是简单批处理一些任务&#xff0c;100 行还是可以干很多的东西的&#xff0c;尤其使用 Python 这种相对高级的语言。但是如果要使用 Bash 这…...

新校区建设网站管理规定/杭州疫情最新情况

如果版本开发测试过程中没有流程的约束&#xff0c;会出现什么样的情况&#xff1f;如果不管版本大小、不考虑版本特性强制使用标准流程约束&#xff0c;又会是什么样&#xff1f;我经常听到的抱怨是流程太厚重了&#xff0c;流程导致了版本开发周期变长、成本增加了。可是&…...