我尝试更改自定义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期间,只能执行绘制Visual内容的绘制操作。
我想在运行时布局过程在实际渲染之前调用GetVisualChild
,而设计画布的运行方式不同?
尝试这是合理的吗?我应该如何触发儿童绘画视觉的渲染,以确保它在法定时间发生?
答案 0 :(得分:0)
您可以通过相应地检测它来阻止在设计时进行渲染
所以,如果我稍微修改你的代码,那么它在设计师中应该表现得很好
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");
}
}
答案 1 :(得分:0)
如果在渲染周期中修改了Visuals本身会抛出异常,设计人员会在渲染周期中获取视觉效果,而无需事先通过排列处理。
但是,即使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");
}
}