C# Programming

WPFXAML 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

四角を描く。

XAML 2D

<Rectangle Stroke="#FF000000" Width="121" Height="81"/>

四角を塗りつぶす描く。

XAML 2D

<Rectangle Fill="#FF1F5AEE" Stroke="#FF000000" Width="117" Height="79" />

四角の角を丸める。

XAML 2D

<Rectangle Stroke="#FF000000" Width="117" Height="79" RadiusX="20" RadiusY="20"/> 

四角の境界線を描く。

XAML 2D

<Rectangle Fill="#FF0A43FA" Stroke="#FFFF0000" StrokeThickness="10" Width="114" Height="77"/>

3.2 楕円

楕円を描く。

XAML 2D

<Ellipse Stroke="#FF000000" Width="121" Height="81"/>

楕円を塗りつぶす描く。

XAML 2D

<Rectangle Fill="#FF1F5AEE" Stroke="#FF000000" Width="117" Height="79" />

楕円の境界線を描く。

XAML 2D

<Ellipse Fill="#FF0000FF" Stroke="#FFFF0000" StrokeThickness="10" Width="114" Height="77" />

3.3 Line

線を描く。

XAML 2D

<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

ポリゴンを描画する。

XAML 2D

線の色の指定方法

<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を描く。

XAML 2D Graphics

左から次の通りです。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。

XAML 2D 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。

XAML 2D 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 。

XAML 2D Geometry

<Path Fill="Cyan" Stroke="Black" StrokeThickness="1">
  <Path.Data>
    <RectangleGeometry Rect="0,0 30,20" />
  </Path.Data>
</Path>

4.4 EllipseGeometry

楕円のGeometry。

XAML 2D 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>

XAML Graphics 2D

ここで、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 (ケースセンシティブ)を使用できます。

これにより、たとえば次のようなベジエ曲線を描くことができます。

XAML 2D Geomery

<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 ・・・任意の数のジオメトリ オブジェクトから複合ジオメトリを作成します。

XAML 2D Graphics

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>

XAML 2D Geometry

このときに、 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つのジオメトリを結合しています。

XAML 2D Geometry

<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を指定することができます。

XAML 2D Graphics

<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+ に比べて、全く新しくなっていますので、その考え方に追い付くのに大変です。

また、破線や矢印など、これまで標準で提供されていたものがなくなっていますが、追加されるのでしょうか・・・今後のエンハンス計画は要注意ですね。