XAML 2D Graphics
開発環境: Visual Studio 2008
1.目的
XAML の2D Graphics を説明します。
2.参考書
(1) XAMLプログラミング
3. 2D Shape
2D Graphics には、Shape(3章)と Geometry (4章) の2種類があります。
基本的なことは押さえておかないとね。
3.1 Rectangle
四角を描く。

<Rectangle Stroke="#FF000000" Width="121" Height="81"/>
四角を塗りつぶす描く。

<Rectangle Fill="#FF1F5AEE" Stroke="#FF000000" Width="117"
Height="79" />
四角の角を丸める。

<Rectangle Stroke="#FF000000" Width="117" Height="79" RadiusX="20"
RadiusY="20"/>
四角の境界線を描く。

<Rectangle Fill="#FF0A43FA" Stroke="#FFFF0000" StrokeThickness="10"
Width="114" Height="77"/>
3.2 楕円
楕円を描く。

<Ellipse Stroke="#FF000000" Width="121" Height="81"/>
楕円を塗りつぶす描く。

<Rectangle Fill="#FF1F5AEE" Stroke="#FF000000" Width="117"
Height="79" />
楕円の境界線を描く。

<Ellipse Fill="#FF0000FF" Stroke="#FFFF0000" StrokeThickness="10"
Width="114" Height="77" />
3.3 Line
線を描く。

<Line X1="100" Y1="50" X2="400" Y2="50" Stroke="black"
StrokeThickness="1"/>
<Line X1="100" Y1="100" X2="400" Y2="100" Stroke="blue"
StrokeThickness="5"/>
<Line X1="100" Y1="150" X2="400" Y2="150" Stroke="red"
StrokeThickness="10"/>
注意: Expression Blend では次のようにPathで描画します。
<Path Fill="#FFFFFFFF" Stretch="Fill" Stroke="#FF000000"
Margin="95,103.5,240,211" Data="M96,104 L383,231"/>
3.4 Polygon
ポリゴンを描画する。

線の色の指定方法
<Polygon Canvas.Left="10" Canvas.Top="10"
Points="5,20 35,20 10,40 20,10 30,40"
Stroke="Black"
Width="43" Height="62" />
塗りつぶしの色の指定方法
<Polygon Canvas.Left="10" Canvas.Top="10"
Points="5,20 35,20 10,40 20,10 30,40"
Fill="cyan"
Width="43" Height="62" />
線と塗りつぶしを指定する
<Polygon Canvas.Left="10" Canvas.Top="10"
Points="5,20 35,20 10,40 20,10 30,40"
Fill="cyan"
Stroke="Black"
Width="43" Height="62"/>
線の太さを指定する
<Polygon Canvas.Left="10" Canvas.Top="10"
Points="5,20 35,20 10,40 20,10 30,40"
Fill="cyan"
Stroke="Black"
StrokeThickness="3"
Width="43" Height="62"/>
塗りつぶしルールの指定(既定では EvenOdd ワインディングルール)
<Polygon Canvas.Left="10" Canvas.Top="10"
Points="5,20 35,20 10,40 20,10 30,40"
Fill="cyan"
Stroke="Black"
FillRule="EvenOdd"
Width="43" Height="62" />
塗りつぶしルールの指定(Nonzero ワインディングルール)
<Polygon Canvas.Left="10" Canvas.Top="10"
Points="5,20 35,20 10,40 20,10 30,40"
Fill="cyan"
Stroke="Black"
FillRule="Nonzero"
Width="43" Height="62" />
3.4 Polyline
Polylineを描く。

左から次の通りです。Polygonとの違いは、線分を閉じるかどうかです。
<Polyline Canvas.Left="10" Canvas.Top="10"
Points="5,20 35,20 10,40 20,10 30,40"
Fill="cyan"
Stroke="Black"
FillRule="EvenOdd"
Width="43" Height="62" />
<Polyline Canvas.Left="10" Canvas.Top="10"
Points="5,20 35,20 10,40 20,10 30,40"
Fill="cyan"
Stroke="Black"
FillRule="Nonzero"
Width="43" Height="62" />
<Polyline Canvas.Left="10" Canvas.Top="10"
Points="5,20 20,10 35,20 30,40 10,40"
Fill="cyan"
Stroke="Black"
FillRule="Nonzero"
Width="43" Height="62" />
4. 2D Geometry
クリッピングやヒットテストを行う場合に、Pathの情報が必要になりますが、描画の必要はありません。そこで、Geometryが出てきます。Geometryでは
2Dのパスであるため、そのパスで描画をすれば、Shapeと同じように、四角や楕円の描画ができてしまいます。
一方、単純な線や四角を描くのであれば、Geometryを使うのは冗長すぎます。このため、ShapeとGeometryの2種類が存在しています。用途に応じて適切に使い分けましょう。
Geometryクラスには、次の派生クラスがあります。
-
LineGeometry
-
PathGeometry
-
RectangleGeometry
-
EllipseGeometry
-
StreamGeometry
-
GeometryGroup
-
CombinedGeometry
4.1 LineGeometry
直線のGeometry。

<Path Fill="Cyan" Stroke="Black" StrokeThickness="1">
<Path.Data>
<LineGeometry StartPoint="10,10" EndPoint="100,10"/>
</Path.Data>
</Path>
4.2 PathGeometry
Path のGeometry。

<Path Fill="Cyan" Stroke="Black" StrokeThickness="1">
<Path.Data>
<PathGeometry>
<PathFigure IsClosed="True" StartPoint="5,20">
<LineSegment Point="35,20"/>
<LineSegment Point="10,40"/>
<LineSegment Point="20,10"/>
<LineSegment Point="30,40"/>
</PathFigure>
</PathGeometry>
</Path.Data>
</Path>
4.3 RectangleGeometry
四角のGeometry 。

<Path Fill="Cyan" Stroke="Black" StrokeThickness="1">
<Path.Data>
<RectangleGeometry Rect="0,0 30,20" />
</Path.Data>
</Path>
4.4 EllipseGeometry
楕円のGeometry。

<Path Fill="Cyan" Stroke="Black" StrokeThickness="1">
<Path.Data>
<EllipseGeometry RadiusX="100" RadiusY="50" Center="100,50"
/>
</Path.Data>
</Path>
4.5 PathGeometry
Path の Geometry。
<Path Fill="Cyan" Stroke="Black" StrokeThickness="1"
Data="M 5,20 L 35,20 L 10,40 L 20,10 L 30,40 Z">
</Path>

ここで、Mとか、Lとか、Zなどは、StreamGeometryのコマンドを意味しています。
この例では、5,20 に移動(M)し、そこから 35,20にパスを引く(L)、同様に 10,40、20,10,
30,40にパスを引く。最後に最初のポイント(5,20)でパスを閉じる(Z)
という動作をします。そのPathデータに対して、シアンで塗りつぶすということです。
コマンド |
説明 |
移動コマンド |
M startPoint または m startPoint |
線コマンド |
L endPoint または l endPoint
|
横線コマンド |
L x または l x |
縦線コマンド |
V y または v y |
3次ベジエ曲線コマンド |
C controlPoint1 controlPoint2 endPoint
または
c controlPoint1 controlPoint2 endPoint
|
2次ベジエ曲線コマンド |
Q controlPoint endPoint
または
q contolPoint endPoint |
平滑 3
次ベジエ曲線コマンド |
S controlPoint2 endPoint
または
s controlPoint2 endPoint |
楕円の円弧コマンド |
A size rotationAngle isLargeArcFlag
sweepDirectionFlag endPoint
または
a size rotationAngle isLargeArcFlag
sweepDirectionFlag endPoint |
閉じるコマンド |
Z または z |
点の構文 |
x , y または x y |
注意 |
値として、Infinity, -Infinity, NaN
(ケースセンシティブ)を使用できます。 |
これにより、たとえば次のようなベジエ曲線を描くことができます。

<Path Fill="Cyan" Stroke="Black" StrokeThickness="1"
Data="M 5,20 C 35,20 10,40 20,10 Z">
</Path>
この詳細については、MSDN
パス マークアップ構文を参照してください。
4.6 CombinedGeometry と GeometryGroup
GeometryGroup、CombinedGeometry を使用することにより、複合ジオメトリ
オブジェクトを作成することができます。
- CombinedGeometry ・・・2 つのジオメトリ
オブジェクトから複合ジオメトリを作成します。
- GeometryGroup ・・・任意の数のジオメトリ
オブジェクトから複合ジオメトリを作成します。

CombinedGeometryで2つの楕円を結合します。
<Path Fill="Cyan" Stroke="Black" StrokeThickness="1">
<Path.Data>
<CombinedGeometry>
<CombinedGeometry.Geometry1>
<EllipseGeometry RadiusX="100"
RadiusY="50" Center="100,50" />
</CombinedGeometry.Geometry1>
<CombinedGeometry.Geometry2>
<EllipseGeometry RadiusX="50" RadiusY="100"
Center="100,50" />
</CombinedGeometry.Geometry2>
</CombinedGeometry>
</Path.Data>
</Path>

このときに、 GeometryCombineMode="XOr"を指定すると、XORでEvenOddワインディングモードで結合できます。
<Path Fill="Cyan" Stroke="Black" StrokeThickness="1">
<Path.Data>
<CombinedGeometry GeometryCombineMode="XOr">
<CombinedGeometry.Geometry1>
<EllipseGeometry RadiusX="100"
RadiusY="50" Center="100,50" />
</CombinedGeometry.Geometry1>
<CombinedGeometry.Geometry2>
<EllipseGeometry RadiusX="50" RadiusY="100"
Center="100,50" />
</CombinedGeometry.Geometry2>
</CombinedGeometry>
</Path.Data>
</Path>
GeometryGroupを使うことにより、複数のジオメトリを結合することができます。次の例では、楕円2つと四角の3つのジオメトリを結合しています。

<Path Fill="Cyan" Stroke="Black" StrokeThickness="1">
<Path.Data>
<GeometryGroup>
<EllipseGeometry RadiusX="100" RadiusY="50"
Center="100,50" />
<EllipseGeometry RadiusX="50" RadiusY="100"
Center="100,50" />
<RectangleGeometry Rect="0,-50 200,200" />
</GeometryGroup >
</Path.Data>
</Path>
GroupGeometryでは、次のようにFillRuleを指定することができます。

<Path Fill="Cyan" Stroke="Black" StrokeThickness="1">
<Path.Data>
<GeometryGroup FillRule="Nonzero">
<EllipseGeometry RadiusX="100" RadiusY="50"
Center="100,50" />
<EllipseGeometry RadiusX="50" RadiusY="100"
Center="100,50" />
<RectangleGeometry Rect="0,-50 200,200" />
</GeometryGroup >
</Path.Data>
</Path>
CombinedGeometryでは、内部のパスは完全に結合されますが、GeometryGroupでは単純に結合されるようです。
5. まとめ
WPF 2D Graphicsでは、Windows.Forms の GDI+
に比べて、全く新しくなっていますので、その考え方に追い付くのに大変です。
また、破線や矢印など、これまで標準で提供されていたものがなくなっていますが、追加されるのでしょうか・・・今後のエンハンス計画は要注意ですね。