Using PathGeometry in Silverlight: An Oddity

I hesitate to characterise this as a bug, because other people have reported that it works for them. But here it is in case knowing it happens, and knowing there’s a workaround might be useful.

I’ve got some code which adds segments to a Path’s PathGeometry in response to mouse clicks. My original project actually added them during an animation, but that doesn’t affect the end result. The problem is that new segments (LineSegment or BezierSegment had the same result) didn’t appear on screen until the surface was forced to re-render. Here’s the relevant code:

Path path = null;

        private void LayoutRoot_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
                Point thisPoint = e.GetPosition(LayoutRoot);
                if (path == null)
                {
                        CreateNewPath(thisPoint);
                        path.LayoutUpdated += new EventHandler(path_LayoutUpdated);
                }
                else
                {
                        path.AddLineElement(thisPoint);
                }
        }

        private void CreateNewPath(Point startPoint)
        {
                path = new Path();
                PathGeometry geometry = new PathGeometry();
                path.Data = geometry;
                PathFigureCollection figures = new PathFigureCollection();
                geometry.Figures = figures;
                PathFigure figure = new PathFigure();
                figures.Add(figure);
                figure.StartPoint = startPoint;
                figure.Segments = new PathSegmentCollection();
                path.Stroke = new SolidColorBrush(Colors.Red);
                path.StrokeThickness = 2;
                path.Stretch = Stretch.None;
                LayoutRoot.Children.Add(path);
        }

What I get when this code runs is that the path gets segments added to it, but they only appear when the control surface has to redraw for some other reason. If you insert a kludge like this after you’ve added the segment it should appear immediately:


    path.Opacity = 0.99;

    path.Opacity = 1.0;

Note that you actually have to change the opacity for the kludge to work, presumably because the PropertyChanged callback won’t get triggered otherwise.

Other things that make the new segments appear are resizing the browser window and causing some other redraw event to happen somewhere on the page. I found that if I had a button on the page and I moved the mouse over it, the mouseover animation was enough to make the segments appear. It looks like adding segments to the geometry isn’t spotted as a change which requires the element to be redrawn, and it feels like a bug to me. The identical code in a WPF application works as expected.

Still, the kludge isn’t too much of a hardship, and in general you’re probably going to be changing other visual elements at the same time as you’re adding your path segments, so perhaps it’s not such a big deal, but I wasted some time trying to figure why my code wasn’t behaving as expected, so perhaps this will help others.

Advertisements

2 comments

  1. Hi Jim,
    I have path data in file, can we read path data in silverlight and render that path data
    file, having path values, two paths is seperated by ” : “, I want to read path from file and want to render those path in silvirlight.

    is it possible in silverlight to read path from file and render that path?

    Thanks in advance!

    with regards
    CP

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s