F#でWPF --- 好きな図形のコントロール作成
下記記事ではXAML上でPathを使って好きな図形を描きました。
XAMLで好きな形を描く - 何でもプログラミング
今回はコード側でコントロールを作成してみます。
作成する図形
Pathの時と同様の図形のコントロールを作成します。
DrawingVisual
Frameworkを継承し、内部でDrawingVisualを利用しています。
AddLogicalChild、AddVisualChildをすることにより、描画部分がマウスイベントを発行するようになります。
open System.Windows open System.Windows.Media type CustomShape() as this = inherit FrameworkElement() let visual = DrawingVisual() do use g = visual.RenderOpen() let pen = Pen(Brushes.Red, 5.0) g.DrawLine(pen, Point(15.0, 15.0), Point(85.0, 85.0)) g.DrawLine(pen, Point(85.0, 15.0), Point(15.0, 85.0)) g.DrawEllipse(null, pen, Point(50.0, 50.0), 50.0, 50.0) this.AddLogicalChild(visual) this.AddVisualChild(visual) override this.VisualChildrenCount = 1 override this.GetVisualChild _ = visual :> Visual
図形を動的に変更
依存プロパティ等によって図形を動的に変える場合、その都度RenderOpenしても更新されません。
間にDrawingGroupを挟むことにより可能となります。
コンストラクタ
let visual = DrawingVisual() let group = DrawingGroup() do use g = visual.RenderOpen() g.DrawDrawing(group)
図形更新
use g = group.Open() // g.Draw...
独自のヒットテスト
HitTestCoreをoverrideすることにより、独自のヒットテストを実行することができます。
有効の場合はPointHitTestResultを、無効の場合はnullを返します。
現在の実装のままではDrawingVisualがHitTestを処理してしまうため、新たにHitTestDisabledDrawingVisualを用意します。
AddLogicalChildとAddVisualChildはこの場合必要ありません。
type HitTestDisabledDrawingVisual() = inherit DrawingVisual() override this.HitTestCore(hitTestParameters : PointHitTestParameters) = null :> HitTestResult type CustomShape() as this = inherit FrameworkElement() let visual = HitTestDisabledDrawingVisual() ... // this.AddLogicalChild(visual) // this.AddVisualChild(visual) ... override this.HitTestCore(hitTestParameters : PointHitTestParameters) = PointHitTestResult(this, hitTestParameters.HitPoint) :> HitTestResult