我创建了自己的FrameworkElement并通过返回我自己的DrawingVisual集合实例来覆盖VisualChildrenCount {get;}和GetVisualChild(int index)。我有覆盖OnRender。
我将在此FrameworkElement中添加20-50个DrawingVisuals,每个DrawingVisual将有2000个线段。这些点的逻辑值介于0到60000之间。当我放大1:1时,FrameworkElement的高度将为60000,退役时间为15分钟!!
如何提高撕裂性能?
答案 0 :(得分:4)
对于这种数据量,我建议您为每个点构建一个包含单个PolyLine的GeometryDrawing和StreamGeometry。然后将它们组合在一个DrawingGroup中,并使用一个DrawingVisual显示它。
这将是XAML:
<DrawingVisual Drawing="{Binding CurrentDrawing}" />
这将是更新CurrentDrawing的代码:
var group = new DrawingGroup();
foreach(var data in myData)
{
StreamGeometry geo = new StreamGeometry();
using(geoContext = geo.Open())
{
geoContext.BeginFigure(myData.StartPoint, false, false);
geoContext.PolyLineTo(myData.AdditionalPoints, true, false);
}
group.Add(new GeometryDrawing
{
Geometry = geo,
Pen = myData.Pen,
});
}
CurrentDrawing = group;
...
如果你的数据正在改变,那么分别创建存储每个GeometryDrawing对象可能是有利的,因此只需要重新创建那些源数据已经改变的GeometryDrawings。
<强>更新强>
您在评论中提到需要单独测试每个20-50个数据项。在这种情况下,您可能希望为每个使用单独的DrawingVisual
。为了获得最佳性能,您需要将RenderOpen()
与DrawingContext
:
IEnumerable<Visual> BuildVisuals()
{
return
from var data in myData
select BuildVisualForData(data);
}
void BuildVisualForData(MyDataType data)
{
var geo = new StreamGeometry();
using(geoContext = geo.Open())
{
geoContext.BeginFigure(myData.StartPoint, false, false);
geoContext.PolyLineTo(myData.AdditionalPoints, true, false);
}
var visual = new DrawingVisual();
using(drawingContext = visual.RenderOpen())
{
drawingContext.DrawGeometry(null, myData.Pen, geo);
}
return visual;
}
答案 1 :(得分:0)
我需要使用hittesting来突出每个视觉效果。如果我使用单个DrawingVisual显示它们,我认为它可能没有完成。
对于这种数据量,我建议您为每个点构建一个包含单个PolyLine的GeometryDrawing和StreamGeometry。然后将它们组合在一个DrawingGroup中,并使用一个DrawingVisual显示它。
这将是XAML:
<DrawingVisual Drawing="{Binding CurrentDrawing}" />
这将是更新CurrentDrawing的代码:
var group = new DrawingGroup();
foreach(var data in myData)
{
StreamGeometry geo = new StreamGeometry();
using(geoContext = geo.Open())
{
geoContext.BeginFigure(myData.StartPoint, false, false);
geoContext.PolyLineTo(myData.AdditionalPoints, true, false);
}
group.Add(new GeometryDrawing
{
Geometry = geo,
Pen = myData.Pen,
});
}
CurrentDrawing = group;
...
如果你的数据正在改变,那么分别创建存储每个GeometryDrawing对象可能是有利的,所以只需要重新创建源数据已经改变的GeometryDrawings