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 中,_hostVisualRootVisual 之间的关系是跨线程可视化的桥梁。让我详细解释它们的关系:

架构关系

复制代码
主线程 (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

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

相关推荐
加号34 小时前
【WPF】自定义颜色拾取器
wpf·自定义颜色拾取器
张人玉4 小时前
WPF 常用样式属性及示例笔记
笔记·wpf
张人玉5 小时前
WPF布局控件(界面骨架核心)
开发语言·c#·wpf·布局控件
亦陈不染8 小时前
c#入门详解(刘铁锰)06 - 数据持久化:TXT文本保存、序列化与反序列化(附详细源码)
开发语言·计算机视觉·c#·wpf
应用市场11 小时前
楼灯光矩阵显示系统:从理论到实践的完整技术方案
线性代数·矩阵·wpf
虚行15 小时前
WPF入门
开发语言·c#·wpf
周杰伦fans16 小时前
MahApps.Metro WPF 开发使用过程中遇到的问题 - 未能加载文件或程序集“Microsoft.Xaml.Behaviors,
microsoft·wpf
△曉風殘月〆1 天前
WPF中的坐标转换
wpf
一个天蝎座 白勺 程序猿1 天前
深度解析:通过ADO.NET驱动Kdbndp高效连接与操作Kingbase数据库
数据库·.net·wpf·kingbase·金仓数据库
时光追逐者1 天前
一个使用 WPF 开发的 Diagram 画板工具(包含流程图FlowChart,思维导图MindEditor)
c#·.net·wpf·流程图