Search code examples
c#wpflinedraw

How to update WPF canvas really fast?


In my wpf app i want to update a line on the canvas(change the start, end point coordinates) and preview the change. The problem is that i add the line but i can only see the initial and final state.

Is there a way to make the line/canvas update itself in real time? I want to see how the line is changing length/position.

for example i receive a list of start/end pairs for the line. if i loop the list and update the coordinates of the line with the values from the pairs i can't see the intermediary states.

i tried to set the visibility for the line and canvas to visible to force them to update but it doesn't work. If i just add new lines, i can't see how they are added, just the final step.

In the code below the method DrawLine is called from a loop every time i have new points.

any suggestions?

public void DrawLine(List<Library2d.Point> points)
{
    PathFigure myPathFigure = new PathFigure();
    myPathFigure.StartPoint = new System.Windows.Point(points.ElementAt(0).X, points.ElementAt(0).Y);

    LineSegment myLineSegment = new LineSegment();
    myLineSegment.Point = new System.Windows.Point(points.ElementAt(1).X, points.ElementAt(1).Y);

    PathSegmentCollection myPathSegmentCollection = new PathSegmentCollection();
    myPathSegmentCollection.Add(myLineSegment);

    myPathFigure.Segments = myPathSegmentCollection;

    PathFigureCollection myPathFigureCollection = new PathFigureCollection();
    myPathFigureCollection.Add(myPathFigure);

    PathGeometry myPathGeometry = new PathGeometry();
    myPathGeometry.Figures = myPathFigureCollection;

    if (myPath == null)
    {            
    myPath = new Path();
    myPath.Stroke = Brushes.ForestGreen;
    myPath.StrokeThickness = 1;
    canvas.Children.Add(myPath);
    }

    myPath.Data = myPathGeometry;
    myPath.Visibility = Visibility.Visible;
    myPath.InvalidateMeasure();

    canvas.Visibility = Visibility.Visible;
    canvas.InvalidateMeasure();
}

Solution

  • The rendering thread has a lower dispatcher priority than the UI thread so you run through the loop in the UI thread applying all the changes at once and then finally the renderer gets a shot at it.

    You should consider binding the line to the data points and update them instead. Here is an article on how to achieve this for polygons: http://bea.stollnitz.com/blog/?p=35 which you could probably adapt for your needs.

    Update: The linked blog has now been archived but can be found on github under: https://github.com/bstollnitz/old-wpf-blog - the polygon binding is starting with article 32