StreamGeometry, 5% -10% boost
protected override void OnRender(DrawingContext context)
{
if (DesignerProperties.GetIsInDesignMode(this))
return;
Stopwatch watch = new Stopwatch();
watch.Start();
var radius = 1.0;
StreamGeometry geometry = new StreamGeometry();
using (StreamGeometryContext ctx = geometry.Open())
{
Point start = new Point(radius * Math.Sin(0) + _offset.X, radius * Math.Cos(0) + _offset.Y);
ctx.BeginFigure(start, false, false);
for (int i = 1; i < 2000; i++, radius += 0.1)
{
Point current = new Point(radius * Math.Sin(i) + _offset.X, radius * Math.Cos(i) + _offset.Y);
ctx.LineTo(current, true, false);
}
}
geometry.Freeze();
Pen pen = new Pen(Brushes.Black, 5);
pen.Freeze();
context.DrawGeometry(null, pen, geometry);
var time = watch.ElapsedMilliseconds;
Dispatcher.InvokeAsync(() =>
{
Window.GetWindow(this).Title = string.Format("{0:000}ms; {1:000}ms", time, watch.ElapsedMilliseconds);
}, DispatcherPriority.Loaded);
}
2
, , . UIElement , , FrameworkElement
public class Graph : UIElement
{
TranslateTransform _transform = new TranslateTransform() { X = 500, Y = 500 };
public Graph()
{
CacheMode = new BitmapCache(1.4);
this.RenderTransform = _transform;
IsHitTestVisible = false;
}
protected override void OnVisualParentChanged(DependencyObject oldParent)
{
base.OnVisualParentChanged(oldParent);
if (VisualParent != null)
(VisualParent as FrameworkElement).MouseMove += (s, a) => OnMouseMoveHandler(a);
}
protected override void OnRender(DrawingContext context)
{
if (DesignerProperties.GetIsInDesignMode(this))
return;
Stopwatch watch = new Stopwatch();
watch.Start();
var radius = 1.0;
StreamGeometry geometry = new StreamGeometry();
using (StreamGeometryContext ctx = geometry.Open())
{
Point start = new Point(radius * Math.Sin(0), radius * Math.Cos(0));
ctx.BeginFigure(start, false, false);
for (int i = 1; i < 5000; i++, radius += 0.1)
{
Point current = new Point(radius * Math.Sin(i), radius * Math.Cos(i));
ctx.LineTo(current, true, false);
}
}
geometry.Freeze();
Pen pen = new Pen(Brushes.Black, 5);
pen.Freeze();
context.DrawGeometry(null, pen, geometry);
var time = watch.ElapsedMilliseconds;
Dispatcher.InvokeAsync(() =>
{
Application.Current.MainWindow.Title = string.Format("{0:000}ms; {1:000}ms", time, watch.ElapsedMilliseconds);
}, DispatcherPriority.Loaded);
}
protected void OnMouseMoveHandler(MouseEventArgs e)
{
var mouse = e.GetPosition(VisualParent as FrameworkElement);
if (e.LeftButton == MouseButtonState.Pressed)
{
_transform.X = mouse.X;
_transform.Y = mouse.Y;
}
}
}
5000 , , .
, ( ). , 1000- , . , .
3
here is an example using DrawingVisualthe lightest approach available in WPF
public class Graph : UIElement
{
DrawingVisual drawing;
VisualCollection _visuals;
TranslateTransform _transform = new TranslateTransform() { X = 200, Y = 200 };
public Graph()
{
_visuals = new VisualCollection(this);
drawing = new DrawingVisual();
drawing.Transform = _transform;
drawing.CacheMode = new BitmapCache(1);
_visuals.Add(drawing);
Render();
}
protected void Render()
{
if (DesignerProperties.GetIsInDesignMode(this))
return;
Stopwatch watch = new Stopwatch();
watch.Start();
using (DrawingContext context = drawing.RenderOpen())
{
var radius = 1.0;
StreamGeometry geometry = new StreamGeometry();
using (StreamGeometryContext ctx = geometry.Open())
{
Point start = new Point(radius * Math.Sin(0), radius * Math.Cos(0));
ctx.BeginFigure(start, false, false);
for (int i = 1; i < 2000; i++, radius += 0.1)
{
Point current = new Point(radius * Math.Sin(i), radius * Math.Cos(i));
ctx.LineTo(current, true, false);
}
}
geometry.Freeze();
Pen pen = new Pen(Brushes.Black, 1);
pen.Freeze();
var time = watch.ElapsedMilliseconds;
context.DrawGeometry(null, pen, geometry);
Dispatcher.InvokeAsync(() =>
{
Application.Current.MainWindow.Title = string.Format("{0:000}ms; {1:000}ms", time, watch.ElapsedMilliseconds);
}, DispatcherPriority.Normal);
}
}
protected override Visual GetVisualChild(int index)
{
return drawing;
}
protected override int VisualChildrenCount
{
get
{
return 1;
}
}
protected override void OnMouseMove(MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
var mouse = e.GetPosition(VisualParent as FrameworkElement);
_transform.X = mouse.X;
_transform.Y = mouse.Y;
}
base.OnMouseMove(e);
}
}