午後わてんのブログ

ベランダ菜園とWindows用アプリ作成(WPFとC#)

WPF、ここ2ヶ月間で行ってきたことのまとめ、矢印図形の移動と編集

ようやくここまでできた
移動できる矢印図形の位置とサイズ、Point追加と削除、直線とベジェ曲線の切り替え、回転

結果

ユーチューブ
youtu.be

GIFアニメーション

結果



ビジュアルツリー

ResizeHandleAdornerクラス

Adornerクラスを継承
対象要素のリサイズで使う、今回はGeoShapeTThumbで使用
これは前回の
gogowaten.hatenablog.com
これのコピペ


AnchorHandleAdornerクラス

Adornerクラスを継承
GeoShapeクラス専用で、アンカーポイントの移動で使う
これは前々回の
gogowaten.hatenablog.com


GeoShapeクラス

Shapeクラスを継承、図形表示
機能は直線とベジェ曲線の切り替え、矢印(矢じり部分)の表示切替など


GeoShapeThumbクラス

Thumbクラスを継承したカスタムコントロール
TemplateにGeoShapeを指定、マウスドラッグ移動できるGeoShape

  • GeoShapeThumb
    • GeoShape



GeoShapeTThumbクラス

これが今回できあがった目的のもの
Thumbクラスを継承したカスタムコントロール
TemplateにGeoShapeThumbを入れたCanvasを指定、マウスドラッグ移動できるGeoShapeThumb
リサイズハンドルでリサイズ可能

  • GeoShapeTThumb
    • Canvas
      • GeoShapeThumb
        • GeoShape



位置とサイズを図形とアンカーハンドルに合わせる

Bounds(位置とサイズ)の取得は

gogowaten.hatenablog.com
このときにだいたいできていた
図形のBoundsの取得に必要なのは

  • 図形のGeometry
  • 図形で使っているPen
  • 図形のRenderTransform

これをGeometryクラスのGetRenderBoundsメソッドを使えば取得できる

図形のBounds取得
DefiningGeometryが図形のGeometryで、これをクローンしたものにRenderTransformを適用してからGetRenderBoundsにPenを渡して取得
クローンを使っているのは、もしそのままのDefiningGeometryにRenderTransformを適用してしまうと、図形とGeometryの両方にRenderTransformが適用されて二重の変形(Transform)になってしまうからで、もとのDefiningGeometryに影響を与えないようにクローンして使っている
図形の位置とサイズに合わせた状態


アンカーハンドルのBounds取得

GetHandlesRenderBounds
図形のアンカーポイント群であるPointCollectionに影響を与えないように別のPointCollectionを用意して、それにRenderTransform(回転)を適用してからBounds取得、それにハンドルサイズを考慮したものがアンカーハンドルのBoundsになる
ハンドルサイズ考慮で使っているRectクラスのInflateは指定した値の分だけ、Rectの位置とサイズを中心から広げる便利なメソッド
(0,0,100,100)のRectにRect.Inflate(20,30)で
(-20,-30,140,160)のRectになる
Inflateメソッド
インフレがあるならデフレもあるのかと思ったけどなかったwマイナス指定で実質のデフレ

図形のBoundsとアンカーハンドルのBoundsを合成(union)して図形と自身に適用

図形とアンカーハンドルに合わせる
2つのBoundsの合成はRectクラスのUnionメソッドを使う
サイズは合成したRectのサイズに合わせる
図形の位置は合成したRectの位置と逆方向になる、そして図形を移動した分は自身の位置はまたその反対側にすることになる
図形とアンカーハンドルに合わせた状態

これで自身の位置とサイズが正しくなるので、ScrollViewer(スクロールバー表示時)で正しく表示されるはず




テストアプリのコード

2025WPF/20250322_GeoShapeThumbThumb at main · gogowaten/2025WPF
github.com


環境




感想

できれば
アンカーハンドル移動時にも即時に位置とサイズを更新したかった
回転の中心軸を図形の左上じゃなくて中心(重心)にしたかった

次はもう少し本番の環境に近いところで動くかどうか




関連記事

次のWPF記事
WPF、矢印図形Thumbのシリアライズテスト - 午後わてんのブログ
gogowaten.hatenablog.com


前回のWPF記事は昨日
WPF、要素をリサイズするときのハンドルThumbをAdornerで作ってみた.mp6 - 午後わてんのブログ
gogowaten.hatenablog.com