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

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

相关推荐
诗仙&李白5 小时前
HEFrame.WpfUI :一个现代化的 开源 WPF UI库
ui·开源·wpf
He BianGu6 小时前
【笔记】在WPF中Binding里的详细功能介绍
笔记·wpf
He BianGu11 小时前
【笔记】在WPF中 BulletDecorator 的功能、使用方式并对比 HeaderedContentControl 与常见 Panel 布局的区别
笔记·wpf
123梦野1 天前
WPF——效果和可视化对象
wpf
He BianGu1 天前
【笔记】在WPF中Decorator是什么以及何时优先考虑 Decorator 派生类
笔记·wpf
时光追逐者2 天前
一款专门为 WPF 打造的开源 Office 风格用户界面控件库
ui·开源·c#·.net·wpf
He BianGu2 天前
【笔记】介绍 WPF XAML 中 Binding 的 StringFormat详细功能
笔记·wpf
Rotion_深3 天前
C# WPF使用线程池运行Action方法
c#·wpf·线程池
攻城狮CSU3 天前
WPF 深入系列.2.布局系统.尺寸属性
wpf