Streamgeometrie gegen Zeichnungskontext.Zeichnungslinie in WPF C#
-
21-12-2019 - |
Frage
Ich werde zeichnen hunderte von Zeilen in Echtzeit.Ich habe die gewählt Visuelle Ebene hierzu.Aber ich sehe, dass es zwei verschiedene Möglichkeiten gibt, hier eine Grenze zu ziehen.Welches schlagen Sie vor, um eine bessere Leistung und Geschwindigkeit zu erzielen?
1.Zeichnungskontext.Zuglinie
public class DrawingTypeOne : FrameworkElement
{
private readonly VisualCollection _visuals;
public DrawingTypeOne(double thickness)
{
var myPen = new Pen
{
Thickness = 1,
Brush = Brushes.White,
};
myPen.Freeze();
_visuals = new VisualCollection(this);
var drawingVisual = new DrawingVisual();
using (var dc = drawingVisual.RenderOpen())
{
dc.DrawLine(myPen, new Point(0,0) , new Point(100,100));
_visuals.Add(drawingVisual);
}
}
protected override Visual GetVisualChild(int index)
{
return _visuals[index];
}
protected override int VisualChildrenCount
{
get
{
return _visuals.Count;
}
}
}
2.Streamgeometrie
public class DrawingTypeTwo : FrameworkElement
{
private readonly VisualCollection _visuals;
public DrawingTypeTwo()
{
_visuals = new VisualCollection(this);
var geometry = new StreamGeometry();
using (var gc = geometry.Open())
{
gc.BeginFigure(new Point(0, 0), true, true);
gc.LineTo(new Point(100,100), true, false);
}
geometry.Freeze();
var drawingVisual = new DrawingVisual();
using (var dc = drawingVisual.RenderOpen())
{
dc.DrawGeometry(Brushes.Red, null, geometry);
}
_visuals.Add(drawingVisual);
}
protected override Visual GetVisualChild(int index)
{
return _visuals[index];
}
protected override int VisualChildrenCount
{
get
{
return _visuals.Count;
}
}
}
Lösung
Wie ich schon sagte, Sie brauchen nur ein Bild und im Inneren können Sie alle Ihre Linien haben.
Schau dir das an:
Zuerst definieren wir mehrere Zeichnungen in unserem Zeichnungskontext:
class EllipseAndRectangle : DrawingVisual
{
public EllipseAndRectangle()
{
using (DrawingContext dc = RenderOpen())
{
// Black ellipse with blue border
dc.DrawEllipse(Brushes.Black,
new Pen(Brushes.Blue, 3),
new Point(120, 120), 20, 40);
// Red rectangle with green border
dc.DrawRectangle(Brushes.Red,
new Pen(Brushes.Green, 4),
new Rect(new Point(10, 10), new Point(80, 80)));
}
}
}
Dies ist das eine spezielle Bild oder Element, das alle Zeichnungen enthält:
public class EllAndRectHost : FrameworkElement
{
private EllipseAndRectangle _ellAndRect = new EllipseAndRectangle();
// EllipseAndRectangle instance is our only visual child
protected override Visual GetVisualChild(int index)
{
return _ellAndRect;
}
protected override int VisualChildrenCount
{
get
{
return 1;
}
}
}
Und so können Sie all diese Dinge in XAML verwenden:
<local:EllAndRectHost Margin="30" ... />
Ich habe über die DrawingVisual Klasse gesprochen, von der Sie erben könnten, anstatt 100 Visuals für 100 Zeilen zu erstellen.
In Bezug auf Ihre Frage ist der erste Ansatz schneller.Weil der zweite Ansatz am Ende das gleiche macht, macht der erste es einfach schön verpackt. DrawLine
ist das unterste Ende.Du kannst nicht tiefer gehen als DrawLine
. DrawGeometry
ruft an DrawLine
und einige andere interne Sachen.