For this kind of data volume, I would suggest you build a GeometryDrawing and StreamGeometry containing a single PolyLine for each of your points. Then combine them all together in a single DrawingGroup and display it using a single DrawingVisual.
This would be the XAML:
<DrawingVisual Drawing="{Binding CurrentDrawing}" />
and this would be the code to update 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;
...
If your data is changing it may be advantageous to create store each GeometryDrawing object separately so it is only necessary to recreate those GeometryDrawings whose source data has changed.
Update
You mention in your comment that you need to separately hittest each of the 20-50 data items. In that case, you probably do want to use a separate DrawingVisual
for each. For maximum performance you will want to use RenderOpen()
with 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;
}