绘图视觉的延迟渲染
本文关键字:延迟 视觉 绘图 | 更新日期: 2023-09-27 18:04:58
我正在尝试更改自定义WPF元素以使用视觉树,以便可以更改背景层而无需丢弃整个保留的渲染。同时,一个图层可能会受到多个属性的影响,所以我想要延迟重做渲染,以防多个属性在一个屏幕更新周期中被更改。我是这么做的。
protected override int VisualChildrenCount
{
get
{
return 1;
}
}
private readonly DrawingVisual textLayer = new DrawingVisual();
bool textLayerReady;
protected override Visual GetVisualChild(int index)
{
switch (index)
{
case 0:
if (!textLayerReady)
{
using (var textContext = textLayer.RenderOpen())
RenderTextLayer(textContext);
}
return textLayer;
default:
throw new ArgumentOutOfRangeException("index");
}
}
它似乎运行正确,但在设计器中我得到:
InvalidOperationException:在OnRender回调期间不能调用此API。在OnRender期间,只能执行绘制可视化内容的绘图操作。
我想,在运行时的布局过程是调用GetVisualChild
之前的实际渲染,和设计画布操作不同?
这是一个合理的尝试吗?我应该如何触发渲染的儿童绘画视觉,以确保它发生在一个合法的时间?
您可以在设计时通过相应地检测来阻止渲染
所以如果我稍微修改一下你的代码它在设计器中也会正常运行
private readonly DrawingVisual textLayer = new DrawingVisual();
bool textLayerReady;
protected override Visual GetVisualChild(int index)
{
if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
{
return; //do not perform custom logic during design time
}
switch (index)
{
case 0:
if (!textLayerReady)
{
using (var textContext = textLayer.RenderOpen())
RenderTextLayer(textContext);
}
return textLayer;
default:
throw new ArgumentOutOfRangeException("index");
}
}
如果在渲染周期中修改视觉效果,则会抛出异常,并且设计人员在渲染周期中获取视觉效果,而无需事先进行安排处理。
然而,在渲染期间修改DrawingGroup
的内容是完全合法的,即使DrawingGroup
是Visual
的成员。
只需要在构造函数中将DrawingGroup
添加到DrawingVisual
一次:
DrawingGroup textLayer = new DrawingGroup();
DrawingVisual textVisual = new DrawingVisual();
using (DrawingContext textContext = textVisual.RenderOpen())
textContext.DrawDrawing(textLayer);
然后,当渲染实际需要时,可以惰性地替换内容,同时仍然保持保留模式的优点(不重建WPF所说的"矢量图形指令列表",对于未更改的图层)。
protected override Visual GetVisualChild(int index)
{
switch (index)
{
case 0:
if (!textLayerReady)
{
using (var textContext = textLayer.Open())
RenderTextLayer(textContext);
}
return textVisual;
default:
throw new ArgumentOutOfRangeException("index");
}
}