WPFとVB.NET、Canvasの中に回転表示したコントロールのドラッグ移動で気づいたこと
RenderTransformやLayoutTransformで
以下はCanvasパネルに表示した場合だけで確認
プロパティ画面から右に10度回転の指定をすると
RotateTransform Angle = "10"がXAMLの方に挿入される
RenderTransformとRotateTransformで回転角度が指定されたことで
Thumbも回転表示される
でも回転したのは見た目だけで内部的には回転していない
右に傾けた青色のThumb
赤枠が元の位置とサイズ
緑枠が回転後のThumbが収まる位置とサイズ
赤丸が元の左上の位置を表す
緑枠の位置とサイズが必要になる
Canvas1の中のThumb1の見た目通りのRect(位置とサイズ)取得
Dim gt As GeneralTransform = thumb1.TransformToVisual(canvas1)これが緑枠になる
Dim s As Size = thumb1.RenderSize
Dim r As Rect = gt.TransformBounds(New Rect(s))
これはOK
納得
全く予想外だったのが
回転表示したコントロール上でのマウスの動きに対する位置の取得!
ThumbコントロールはDragDeltaイベントで
マウスドラッグの移動距離を簡単に取得できるので
これを使ってどんな値が取得できているのか見てみた
回転前では普通に横の値が変化しているけど
右に90度回転した後だと縦の値が変化していて上に移動していることになっている
つまり回転角度に合わせてマウスの位置も変換されているみたい
うーん、これはある意味見た目通りの動きなのかも?
このわかりづらい罠みたいな動きはThumbのDragDeltaイベントだけじゃなくて
その他のコントロールでのMouseMoveイベントでも同じだった
回転させたものをドラッグ移動させると
ウィンドウの外に勢い良くすっ飛んでいく原因を探っていて気づいたけど
1週間くらいかかったYO!
気づいたのはいいけど今度は期待通りの値を取得する方法がわからない
思いついたのが
WPFとVBでアプリ作る準備その2、ControlTemplateの中のControlを取得する ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログこの時に使ったControlTemplateを使う方法
http://blogs.yahoo.co.jp/gogowaten/13906217.html
XAMLのほうで
Thumb.Template
ControlTemplate
Image
ってThumbのControlTemplateにImageを入れておいてImageだけを回転させれば
Thumbから取得できるマウスの値は期待したものになるし
画像も回転表示できる
中のImageを回転させるためには
対象となるThumbのTemplateの中にあるimage1と名前を付けておいたImageを取得、tがThumb
'テンプレートの中のコントロールを取得するTemplate.FindName
Dim img As Image = t.Template.FindName("image1", t)
あとはImageに対してRotateTransformを使って回転させればいい
Imageを30度回転するとき
Dim rt As New RotateTransform(30)
Image.RenderTransform = rt
Image.RenderTransform = rt
ふつうにできる
回転後はImageのサイズが変わるけどThumbも自動で変わるので
指定する必要はないみたい?
ただし両方共見た目だけが変化しただけで内部では回転前の位置とサイズ
なのはプロパティのRenderSizeとか見るとわかる
回転後の見た目通りのRect(位置とサイズ)を取得、上の例だと緑枠の取得するには
Imageを対象にする
tがThumb、canvas1がCanvas
Dim img As Image = t.Template.FindName("image1", t)
Dim gt As GeneralTransform = img.TransformToVisual(canvas1)
Dim s As Size = img.RenderSize
Dim r As Rect = gt.TransformBounds(New Rect(s))
Dim gt As GeneralTransform = img.TransformToVisual(canvas1)
Dim s As Size = img.RenderSize
Dim r As Rect = gt.TransformBounds(New Rect(s))
そんなこんなで回転や拡大をできるようになった
画像の回転はWindowsフォームアプリのときは結構手間がかかったんだけど
WPFでは実質2行でできるから簡単にできそうだなって思って作り始めたら
思わぬところで時間がかかったw
でももっと作りこんでから気づいた場合は書き直しがもっと大変だろうから
今回気づけてよかった
アプリとソース一式ダウンロード先
ヤフーボックス
2016年5月22日追記
関連記事、3ヶ月後
WPFとVB.NET、ControlTemplateを使ったThumbを回転表示する時に回転させるのはどれがいいのか ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14157487.html
2017年6月29日は4ヶ月後
WPF、変形した要素を指定位置に移動、NotifyProperty ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/14998511.html
7年後