WPF 更改 DrawingVisual 的 RenderOpen 用到的对象的内容将持续影响渲染效果

本文探讨了在WPF中使用DrawingVisual进行底层绘制时,如何利用DrawingContext和Transform对象。当尝试复用TranslateTransform以减少内存影响时,发现其在DrawignContext内的PushTransform操作并未复制Transform,而是记录引用。这意味着Transform的更改会影响后续渲染,导致意外的界面效果。作者分享了一个有趣的动画现象,并强调RenderOpen后对Transform的修改会在渲染时体现。博客提供相关代码示例并邀请读者交流讨论。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在 WPF 里面,可以通过 DrawingVisual 来进行使用底层的绘制方法,此方法需要调用 DrawingVisual 的 RenderOpen 拿到 DrawingContext 类型的对象,接着调用此对象的方法来进行界面绘制。在绘制完成之后,如果依然保存绘制过程的对象,例如 Transform 对象,那当界面再次刷新时,如果更改此对象的属性,将会影响渲染

似乎这不是一个可以做简单描述的问题,其实这个问题也让我前天花了半天的时间才解决的一个界面渲染问题的其中一个。我在编写一个简单的轻量的文本库的时候,发现了文本字排版存在了一点问题。我的文本排版才能的是将文本转换为 Geometry 对象,接着在 DrawingContext 里面绘制出来。我为了实现让文本可以叠加特效的功能,因此不采用 GlyphRun 类型,同时为了减少 Geometry 对象的创建,我不能在 Geometry 对象上叠加变换

因为为了让文本的字能排版对,我就需要设置每个字在界面绘制的坐标。为了简化逻辑,我采用一个 RectangleGeometry 来代替文字的 Geometry 对象。如基础的知识,在 DrawingContext 里面如果想要在指定的地方绘制某个内容,可以采用的方法是调用 PushTransform 方法,设置当前绘制的变换,也就包括了设置当前绘制在哪,如下面代码

            var drawingVisual = new DrawingVisual();
            using (var drawingContext = drawingVisual.RenderOpen())
            {
                var rectangleGeometry = new RectangleGeometry(new Rect(0, 0, 10, 10));

                for (int i = 0; i < 10; i++)
                {
                    var translateTransform = new TranslateTransform();

                    translateTransform.X = i * 15;

                    drawingContext.PushTransform(translateTransform);

                    drawingContext.DrawGeometry(Brushes.Red, null, rectangleGeometry);

                    drawingContext.Pop();
                }
            }

此时的界面能工作,大概如下

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值