WPF 具有跨线程功能的UI元素

概括

VisualTarget 本身继承自 CompositionTarget,而不是 Visual;其本身并不是可视化树的一部分。但是它的构造函数中可以传入一个 HostVisual 对象,这个对象是一个 Visual,如果将此 HostVisual 放入原 UI 线程的可视化树上,那么 VisualTarget 就与主 UI 线程连接起来了。

另外一半,VisualTarget 需要连接另一个异步线程的可视化树。然而,VisualTarget 提供了 RootVisual 属性,直接给此属性赋一个后台 UI 控件作为其值,即连接了另一个 UI 线程的可视化树。

代码:

cs 复制代码
 /// <summary>
 /// 此控件具有跨线程更新功能
 /// </summary>
 public class DispatcherContainer : UIElement
 {
     /// <inheritdoc />
     public DispatcherContainer()
     {

         ThreadUpdate();
     }

     public void ThreadUpdate()
     {
         var thread = new Thread(() =>
         {
             _visualTarget = new VisualTarget(_hostVisual);
             DrawingVisual drawingVisual = new DrawingVisual();
             var drawing = drawingVisual.RenderOpen();
             using (drawing)
             {
                 var text = new FormattedText("欢迎访问",
                     CultureInfo.CurrentCulture, FlowDirection.LeftToRight,
                     new Typeface(new FontFamily("微软雅黑"), new FontStyle(), FontWeight.FromOpenTypeWeight(1),
                         FontStretch.FromOpenTypeStretch(1)), 20, Brushes.DarkSlateBlue);

                 drawing.DrawText(text, new Point(100, 100));
             }

             var containerVisual = new ContainerVisual();

             containerVisual.Children.Add(drawingVisual);

             _visualTarget.RootVisual = containerVisual;


            

             System.Windows.Threading.Dispatcher.Run();
         });




         thread.SetApartmentState(ApartmentState.STA);
         thread.Start();
     }

     /// <inheritdoc />
     protected override Visual GetVisualChild(int index)
     {
         return _hostVisual;
     }

     /// <inheritdoc />
     protected override int VisualChildrenCount => 1;

     private readonly HostVisual _hostVisual = new HostVisual();
     private VisualTarget _visualTarget;
 }

使用:

解释:

先理解Host 和 Root含义:

Host是宿主,Root是根基,大概是Root可以放在Host里面,Host是Root的载体的意思;

VisualTarget 的解释:提供跨线程边界将一个可视化树连接到另一个可视化树的功能。

拆分理解一下:提供了 跨线程的(副词) 连接可视化树(动词) 的功能。

简单理解为:可以跨线程拼接UI元素

与主线程连接:

上述控件的_hostVisual 字段属于主线程(UI 线程)的可视化树上,创建_visualTarget实例,把【DispatcherContainer 的_hostVisual 字段】赋值给【_visualTarget私有的_hostVisual字段】;

代码表现为:

cs 复制代码
 _visualTarget = new VisualTarget(_hostVisual);

即_visualTarget通过关联了_hostVisual 间接的关联了UI线程;

与子线程连接:

//创建可视化对象,添加由DrawingVisual绘制的内容

var containerVisual = new ContainerVisual();

containerVisual.Children.Add(drawingVisual);

//关联_visualTarget和子线程的可视化树

_visualTarget.RootVisual = containerVisual;

即_visualTarget通过关联了【子线程创建的containerVisual】间接的关联了子线程;

AI分析:

在 WPF 的 VisualTarget 中,_hostVisual 和 RootVisual 之间的关系是跨线程可视化的桥梁。让我详细解释它们的关系:

架构关系

复制代码
主线程 (UI Thread)
│
├── HostVisual (_hostVisual)
│   └── 作为占位符嵌入主可视化树
│
└── 通过 VisualTarget 连接到 ↓

后台线程 (STA Thread)
│
├── VisualTarget (_visualTarget)
│   └── 连接到主线程的 HostVisual
│       └── RootVisual (容器视觉)
│           └── 实际的可视化内容(文字、图形等)

详细关系说明

1. HostVisual (_hostVisual) - 主线程

  • 角色:在主可视化树中的"占位符"或"代理"

  • 位置:位于主 UI 线程的可视化树中

  • 作用:为跨线程的可视化内容提供一个连接点

2. VisualTarget - 跨线程连接器

  • 角色:连接不同线程间可视化树的桥梁

  • 构造 :new VisualTarget(_hostVisual) 建立与 HostVisual 的连接

  • 作用:管理线程间的可视化数据传递

3. RootVisual - 后台线程的根

  • 角色:后台线程可视化树的根节点

  • 位置:位于后台线程的可视化树中

  • 作用:包含实际要显示的可视化内容

总结

其他文章展示的代码大同小异,思想就是一个HostVisual 对象A 在主线程可视化树上,然后有一个子线程的UI对象B ,然后A 关联VisualTarget 对象的一个字段:_hostVisual ,B关联VisualTarget 对象的一个属性:RootVisual,实现B替换A的效果;

引用:

https://lindexi.blog.csdn.net/article/details/103184442?fromshare=blogdetail&sharetype=blogdetail&sharerId=103184442&sharerefer=PC&sharesource=qq_59062726&sharefrom=from_link

https://www.cnblogs.com/walterlv/p/10236528.html

https://blog.csdn.net/amanda_zhang2010/article/details/68946798?fromshare=blogdetail&sharetype=blogdetail&sharerId=68946798&sharerefer=PC&sharesource=qq_59062726&sharefrom=from_link

https://www.cnblogs.com/Zhouyongh/archive/2011/01/12/1933414.html

一点个人浅见,未必周全,权当抛砖引玉。若有疏漏之处,还请大家一起指正讨论。

相关推荐
samble3 天前
从零搭建灌装监控系统(四):深色主题与样式系统,ResourceDictionary 统一管理
c#·wpf·mvvm·样式·工业控制
_Jonas3 天前
.net framework开发环境正式环境配置文件的切换
.net·wpf
dalong105 天前
WPF:Modbus 状态监控
wpf·modbus
He BianGu6 天前
【WPF-VisionMaster】机器视觉通用平台V5.0版本发行说明
opencv·c#·wpf·halcon·机器视觉·visionmaster
fogota9 天前
Emoji与Segoe MDL2 Assets的比较
c#·wpf
fogota9 天前
C# WPF 按钮加载字体图标 / 动物头像
c#·.net·wpf
fogota9 天前
C# WPF 按钮加载系统图标 / 动物头像
c#·.net·wpf
军训猫猫头9 天前
C# 封装 MySQL 自动写入与查询工具类(基于 MySqlConnector)
mysql·c#·.net·wpf
gis开发之家10 天前
Spring Boot 4 定时任务与异步线程池:从 @Scheduled 到高并发任务编排(生产级实战)
java·spring boot·后端·wpf·spring boot4
clz131452111 天前
如何设计一个优雅可靠的金融级联机接口
wpf