Monday, September 17, 2012

Cloning a PathGeometry in Silverlight / WPF

Cloning a PathGeometry in Silverlight / WPF

I have a simple handler that adds an ellipse to an empty Silverlight canvas

    private void UCLoaded(object sender, RoutedEventArgs e)     {         var geometry = MakeElipse(20, 15, new Point(100, 100));         var ellipsePath = new Path         {             Data = geometry,             Fill = new SolidColorBrush(Colors.DarkGray),             StrokeThickness = 4,             Stroke = new SolidColorBrush(Colors.Gray)         };         LayoutRoot.Children.Add(ellipsePath);         //         var duplicateEllipsePath = new Path();         //duplicateEllipsePath.Data = ellipsePath.Data;          duplicateEllipsePath.Data = geometry;         duplicateEllipsePath.Fill = ellipsePath.Fill;          duplicateEllipsePath.StrokeThickness = ellipsePath.StrokeThickness;         duplicateEllipsePath.Stroke = ellipsePath.Stroke;         LayoutRoot.Children.Add(duplicateEllipsePath);     } 

The first ellipse, ellipsePath, is fine and renders as expected. But the line duplicateEllipsePath.Data = ellipsePath.Data or the alternative duplicateEllipsePath.Data = geometry each throw the System.ArgumentException "Value does not fall within the expected range". How can it be in range once, and out-of-range immediately afterwards? What is the correct way of duplicating a path in code like this?

Answers & Comments...

Answer: 1

It looks like the only way to clone a path is to do so manually. To quote this answer from Yi-Lun Luo:

The Data property is actually a Geometry. While not noticeable in Silverlight, A Geometry actually relies on an underlying system resource (because it needs to draw something). If you need to draw another Geometry, you'll need another system resource. So you must clone it before you assign it to a new Path. In WPF, we do have a Clone method on Geometry, unfortunately this is not supported in Silverlight. So you have to manually do the clone.

Another post above Yi-Lun's claims to contain reflective code to clone a geometry, and the same code seems to appear here, although the latter is more clearly formatted. However, in your case, it seems overkill to use a method such as this. The geometry you use is created by your MakeElipse [sic] method. Extracting the common code to generate the geometries into a method seems about the best way to proceed here.

The error message 'Value does not fall within the expected range' is a bit misleading. I don't see anything 'out of range', given that the exact same object was supposedly in range for your first ellipse. I can't say exactly why this error message is reported, but I can speculate. Silverlight is implemented in native code, and I believe that because the native code can't throw exceptions it instead returns numeric error codes. Perhaps there's a limited number of error codes and the one for 'Value does not fall within the expected range' was the one chosen for this error?

by : Luke Woodwardhttp://stackoverflow.com/users/48503




No comments:

Post a Comment

Send us your comment related to the topic mentioned on the blog