Sunday, January 13, 2013

Port Shape to Silverlight

Port Shape to Silverlight

I need to port some custom shapes we are displaying in a WPF control to Silverlight. When I did those I extended the Shape class like this:

public abstract class MyShape:Shape {       public static readonly DependencyProperty SizeProperty = DependencyProperty.Register("Size", typeof(Double), typeof(MapShape), new UIPropertyMetadata(new PropertyChangedCallback(SizeChanged)));      public static readonly DependencyProperty RotationAngleProperty = DependencyProperty.Register("RotationAngle", typeof(Double), typeof(MapShape), new PropertyMetadata(0.0d));      public double Size     {         get { return (double)this.GetValue(SizeProperty); }         set { this.SetValue(SizeProperty, value); }     }      public double RotationAngle     {         get { return (double)this.GetValue(RotationAngleProperty); }         set { this.SetValue(RotationAngleProperty, value); }     }      private static void SizeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)     {         MapShape shape = (MapShape)d;         shape.InvalidateVisual();                }      protected override Geometry DefiningGeometry     {         get         { return null; }     } } 

That allowed me to control important properties (for this project at least) such as the size, rotation angle of the shape and the Size changed event. From this abstract base class I created some very specific classes like this arrow:

public class Arrow : MyShape {     public Arrow()     {     }      protected override Geometry DefiningGeometry     {         get         {             double oneThird = this.Size / 3;             double twoThirds = (this.Size * 2) / 3;             double oneHalf = this.Size / 2;              Point p1 = new Point(0.0d, oneThird);             Point p2 = new Point(0.0d, twoThirds);             Point p3 = new Point(oneHalf, twoThirds);             Point p4 = new Point(oneHalf, this.Size);              Point p5 = new Point(this.Size, oneHalf);             Point p6 = new Point(oneHalf, 0);             Point p7 = new Point(oneHalf, oneThird);               List<PathSegment> segments = new List<PathSegment>(3);             segments.Add(new LineSegment(p1, true));             segments.Add(new LineSegment(p2, true));             segments.Add(new LineSegment(p3, true));             segments.Add(new LineSegment(p4, true));              segments.Add(new LineSegment(p5, true));             segments.Add(new LineSegment(p6, true));             segments.Add(new LineSegment(p7, true));              List<PathFigure> figures = new List<PathFigure>(1);             PathFigure pf = new PathFigure(p1, segments, true);             figures.Add(pf);             RotateTransform rt = new RotateTransform(this.RotationAngle);              rt.CenterX = oneHalf;             rt.CenterY = oneHalf;              Geometry g = new PathGeometry(figures, FillRule.EvenOdd, rt);              return g;         }     } } 

That was all cool and dandy but now comes silverlight and it does not seem to have a Shape class with a DefiningGeometry function but a Path class... what??? So, I did a quick search on-line and found some examples. They display on my Silverlight control but when we push the control with 500 points of data (which we routinely do with this application in the WPF version) the whole darn thing crashes and starts complaining (yes, I am frustrated!). I get this error:

Message: Layout cycle detected.  Layout could not complete. 

So, anyone with a similar problem who was able to solve it nicely has any ideas? Thanks!

Answers & Comments...




No comments:

Post a Comment

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