2009年11月6日 星期五

在WPF中自訂形狀(Shape)

在WPF的UI設計中,有時候會需要特殊形狀的控制項
可以使用ImageBrush以及透明背景的一張圖
將控制項(如Border)繪製成不規則形狀
(參考在WPF中使用影像筆刷(ImageBrush))
但是這種做法有個缺點,就是實際上的控制項並不是不規則的
所以如果要做成鑲嵌在一起的一些控制項就會因為互相覆蓋而造成問題

第二種就是用現有的基本形狀(Shape),如方形、橢圓等組合成新的控制項
可以利用Union, Xor, Intersect, Exclude兩兩組合
從而做出許多變化,例如

<Path Fill="Black">
<Path.Data>
<CombinedGeometry GeometryCombineMode="Xor">
<CombinedGeometry.Geometry1>
<EllipseGeometry Center="50,50"
RadiusX="30"
RadiusY="30" />
</CombinedGeometry.Geometry1>
<CombinedGeometry.Geometry2>
<EllipseGeometry Center="100,50"
RadiusX="30"
RadiusY="30" />
</CombinedGeometry.Geometry2>
</CombinedGeometry>
</Path.Data>
</Path>

上面就是兩個圓直接做Xor,顯示出來的圖會是

這樣的做法雖然已經可以做出一些很特別的控制項了
但是畢竟彈性還是有限,所以同樣使用Path,還可以用更彈性的方法來做
將上述例子中的CombinedGeometry中換成PathGeometry

<PathGeometry>
<PathGeometry.Figures>
<PathFigureCollection>
<PathFigure IsClosed="True"
StartPoint="10,10">
<PathFigure.Segments>
<PathSegmentCollection>
<ArcSegment Point="50,50"
Size="50,50"
SweepDirection="Clockwise"/>
<LineSegment Point="50,10" />
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
</PathFigureCollection>
</PathGeometry.Figures>
</PathGeometry>

同樣的效果也可以用C#寫

private Path AddShape()
{
/// set path with stroke
Path p = new Path();
p.Stroke = Brushes.Black;
p.StrokeThickness = 1;

/// set path figure with start and IsClosed
PathFigure pf = new PathFigure();
pf.IsClosed = true;
pf.StartPoint = new Point(10,10);

/// add two segments
pf.Segments.Add(new ArcSegment(
new Point(50,50), new Size(50,50), 0,
false, SweepDirection.Clockwise, true));
pf.Segments.Add(new LineSegment(
new Point(50,10), true));

/// set the data as the new path figure
p.Data = new PathGeometry();
(p.Data as PathGeometry).Figures.Add(pf);

return p;
}

在這邊的路徑片段(Segment)都代表從現在的點到一個點
然後構成一整條路徑,再將其填滿,可分成
種類說明
LineSegment直線段,只需設定目的點(Point),即會從目前所在連成一條直線段
ArcSegment弧線段,除目的點(Point)外,還需要設定弧形大小(Size,橢圓的長短軸)、軸旋轉角度(RotationAngle,預設為0)、線段轉彎方向(SweepDirection),以及是否轉彎超過180度(IsLargeArc)
PolyLineSegment多線段,設定一組連續的點(Points),即會從目前所在依照順序連接起來
BezierSegment三次貝茲曲線,設定目的點(Point3)以及兩個控制點(Point1, Point2)
PolyBezierSegment多段三次貝茲曲線,設定一組連續點(Points),其中每三個為一小組,代表經過兩控制點到目的點的一段三次貝茲曲線
QuadraticBezierSegment二次貝茲曲線,設定目的點(Point2)以及一個控制點(Point1)
PolyQuadraticBezierSegment多段二次貝茲曲線,設定一組連續點(Points),其中每兩個為一小組,代表經過控制點到目的點的一段二次貝茲曲線

--
參考資料
Path 類別
HOW TO:建立複合圖案
HOW TO:使用 PathGeometry 建立圖案
PathSegment 類別

沒有留言:

張貼留言