F#でWPF --- 好きな図形のコントロール作成 --- Geometry利用

下記記事にて好きな図形のコントロールを作成しました。
F#でWPF --- 好きな図形のコントロール作成 - 何でもプログラミング

その際、独自のヒットテストを実装しようとすると、ロジックを一から実装しなければなりませんでした。

今回はGeometryクラスを用いてヒットテストの実装を楽にしてみます。

描画する図形

前記事と同じ図形を描画します。
f:id:any-programming:20170221002105p:plain

CustomShape

Geometryを定義し、描画の際はDrawGeometryを利用し、ヒットテストの際はStrokeContains(もしくはFillContains)を利用します。

HitTestDisabledDrawingVisualは前記事を参照してください。

type CustomShape() =
    inherit FrameworkElement()
    let visual = HitTestDisabledDrawingVisual()
    let lines  = [ LineGeometry(Point(15.0, 15.0), Point(85.0, 85.0))
                   LineGeometry(Point(85.0, 15.0), Point(15.0, 85.0)) ]
    let circle = EllipseGeometry(Point(50.0, 50.0), 50.0, 50.0)
    let pen = Pen(Brushes.Red, 5.0)
    let group = DrawingGroup()    
    do  use g = visual.RenderOpen()
        lines |> List.iter (fun x -> g.DrawGeometry(null, pen, x))
        g.DrawGeometry(null, pen, circle)

    override this.VisualChildrenCount = 1

    override this.GetVisualChild _ = visual :> Visual

    override this.HitTestCore(hitTestParameters : PointHitTestParameters) =         
        if lines |> List.exists (fun x -> x.StrokeContains(pen, hitTestParameters.HitPoint)) ||
           circle.StrokeContains(pen, hitTestParameters.HitPoint) then
            PointHitTestResult(this, hitTestParameters.HitPoint) :> HitTestResult
        else
            null :> HitTestResult


動的に描画内容を変更

前記事と同じく、DrawingGroupクラスを間に介入させることにより、動的に図形を変更することが可能です。

let group = DrawingGroup()
do  use g = visual.RenderOpen()
    g.DrawDrawing(group)

...
use g = group.Open()
g.DrawGeometry(geometry)