2012-03-05 14 views
0

基本的には六角形ですが、いくつかの追加のプロパティとメソッドを持つカスタムシェイプクラスを作成しようとしています。コンストラクタでカスタムシェイプクラスを表示する方法

私はPolygonクラスからそれを継承しようとしたが、Polygonクラスが封入されているとして、それは、それを許可しませんので、私は抽象Shapeクラスからそれを継承したが、次に何をすべきか分かりません。

<local:Cell Center="20,20" Radius="10" Stroke="Blue" Fill="White"/> 

そして私はまた、コンストラクタで見えるようにしたい:これまでのところ私のコードは、今、この

public class Cell : Shape 
{ 
    private Polygon poly; 
    private Point[] points = new Point[6]; 
    public PointCollection Points { get; set; } 
    public double Radius { get; set; } 
    public Point Center { get; set; } 
    public Cell() 
    { 
     points[0] = new Point(Center.X - 1/2 * Radius, Center.Y - Radius * 0.866); 
     points[1] = new Point(Center.X + 1/2 * Radius, Center.Y - Radius * 0.866); 
     points[2] = new Point(Center.X + Radius, Center.Y); 
     points[3] = new Point(Center.X + 1/2 * Radius, Center.Y + Radius * 0.866); 
     points[4] = new Point(Center.X - 1/2 * Radius, Center.Y + Radius * 0.866); 
     points[5] = new Point(Center.X - Radius, Center.Y); 

     Points = new PointCollection(); 
     foreach (Point p in points) 
      Points.Add(p); 
     poly = new Polygon(); 
     poly.Points = this.Points; 
    } 
} 

のように見える、私のようなXAMLでそれを宣言することができるようにしたいです。

これを行うには、他に何を追加する必要がありますか?私が実装する必要がある、またはオーバーライドする必要があるメソッドがある特定のインターフェイスはありますか?

+0

、彼らは関係なく、あなたを助けることが確実にWPF、Silverlightの&WP7は、この上の異なるアプローチを持っていると同じように、技術について具体的にしてくださいする方法がわかりません何とか互換性があります。 – NestorArturo

+0

Ok - Silverlight for WP7 –

答えて

2

私は半円の形を作り出すのに似たようなことをしました。 Shapeから継承し、DefiningGeometryとMeasureOverrideをオーバーライドする必要があります。ジオメトリの定義では、実際の図面を実行してジオメトリを返します。

プロパティをXAMLで表示するには、クラスにプロパティを追加するだけです。 Plain .NETのプロパティが表示されますが、依存プロパティを追加し、AffectsRender FrameworkPropertyMetadataOptionsを設定して、プロパティを変更したときに強制的に再描画する必要があります。

はここに私のクラスには、ように見えたものです:

public class SemiCircle : Shape 
{ 
    /// <summary> 
    /// Gets or set the alignment of the semicircle. I.e. where should the flat part point. 
    /// </summary> 
    public SemiCircleAlignment Alignment 
    { 
     get { return (SemiCircleAlignment)GetValue(AlignmentProperty); } 
     set { SetValue(AlignmentProperty, value); } 
    } 

    // Using a DependencyProperty as the backing store for alignment. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty AlignmentProperty = 
     DependencyProperty.Register("Alignment", typeof(SemiCircleAlignment), typeof(SemiCircle), 
     new FrameworkPropertyMetadata(SemiCircleAlignment.Top,FrameworkPropertyMetadataOptions.AffectsRender)); 

    protected override System.Windows.Media.Geometry DefiningGeometry 
    { 
     get 
     { 
      StreamGeometry geometry = new StreamGeometry(); 
      using (StreamGeometryContext context = geometry.Open()) 
      { 
       DrawSemiCircle(context); 
      } 
      geometry.Freeze(); 
      return geometry; 
     } 
    } 

    protected override Size MeasureOverride(Size constraint) 
    { 
     if (constraint.Height == double.PositiveInfinity || constraint.Width == double.PositiveInfinity) 
     { 
      if (double.IsNaN(Width) || double.IsNaN(Height)) 
      { 
       return new Size(0, 0); 
      } 
      return new Size(Width, Height); 
     } 
     return constraint; 
    } 

    private void DrawSemiCircle(StreamGeometryContext context) 
    { 
     double tOff = StrokeThickness/2.0;    // an offset to account for stroke thickness 
     Point startPt = new Point(tOff, tOff);         // upper left corner 
     if (Alignment == SemiCircleAlignment.Bottom || Alignment == SemiCircleAlignment.Right) 
     { 
      startPt = new Point(ActualWidth - tOff, ActualHeight - tOff);  // or lower right corner 
     } 
     Point endPt = new Point(ActualWidth - tOff,tOff);       // upper right corner 
     if (Alignment == SemiCircleAlignment.Left || Alignment == SemiCircleAlignment.Bottom) 
     { 
      endPt = new Point(tOff, ActualHeight - tOff);       // or lower left corner 
     } 
     Size s = new Size(Math.Max(0.0,(ActualWidth/2) - tOff), 
      Math.Max(0,ActualHeight - StrokeThickness)); // half width is radius 
     SweepDirection sweep = SweepDirection.Counterclockwise;  
     if (Alignment == SemiCircleAlignment.Left || Alignment == SemiCircleAlignment.Right) 
     { 
      s = new Size(Math.Max(0,ActualWidth - StrokeThickness), 
       Math.Max(0.0,(ActualHeight/2) - tOff));  // or half height is radius 
      sweep = SweepDirection.Clockwise; 
     } 

     context.BeginFigure(startPt, true, true); 
     context.ArcTo(endPt, s, 0, false, sweep, true, false); 
    } 
} 

public enum SemiCircleAlignment { Left, Top, Right, Bottom }; 
+0

ありがとうございました! –

+0

私はクラスのシェイプを見つけることができません。どんな方向? @RickardB。 –

+0

それは[System.Windows.Shapes.Shape](http://msdn.microsoft.com/en-us/library/system.windows.shapes.shape(v = vs.110).aspx) –

関連する問題