午後わてんのブログ

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

WPFとVB.NET、ControlTemplateを使ったThumbを回転表示する時に回転させるのはどれがいいのか

 
 
ControlTemplateを指定したThumbを回転表示させたものをドラッグ移動したら
動きがおかしくてマウスとは違う方向に動いていく
これは
WPFVB.NETCanvasの中に回転表示したコントロールのドラッグ移動で気づいたこと ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/13947862.html
この時に書いたのをすっかり忘れていたからなんだけど
この時とは別の方法でできたのでメモ
その方法は
Thumbを回転させるのではなくてTemplateに指定したCanvasを回転させる
これだけ
 
試しにThumbのTemplateプロパティに
Canvasを入れたControlTemplateを指定して
そのCanvasの中にRectangleとtextBlockを入れたものを表示
Thumb
┣Rectangle
┗textBlock
これを
それぞれの方法で60度回転表示させたものをマウスドラッグ移動しているのが
イメージ 1
左 Thumbを回転表示
中 Thumbの中のCanvasを回転表示
右 Thumbの中のRectangleとtextBlockを回転表示
 
左のThumbを回転表示したものだけ動きがおかしいw
中と右は動きがまともなのでこのどちらかを使うことになりそう
中央のCanvasを回転表示するのがいいかなあ
 
デザイン画面とXAML

f:id:gogowaten:20191030115035p:plain

 
VBコード

f:id:gogowaten:20191030115048p:plain

'ThumbのTemplateを指定した時どれを回転させればドラッグ移動がうまくいくのか
'結果はThumb以外のどれかが良さそう
'Template中のCanvasCanvasの中に入れたものになるけど
'Canvasがいいかなあってところ
Imports System.Windows.Controls.Primitives

Class MainWindow
    'Thumbの座標セット
    Private Sub SetLocate(obj As Object, p As Point)
        Canvas.SetLeft(obj, p.X)
        Canvas.SetTop(obj, p.Y)
    End Sub

    'Thumbの座標ゲット
    Private Function GetLocate(obf As Object) As Point
        Return New Point(Canvas.GetLeft(obf), Canvas.GetTop(obf))
    End Function

    'Thumbのマウスドラッグイベント用
    Private Sub ThumbDragDelta(sender As Object, e As DragDeltaEventArgs)
        Dim t As Thumb = DirectCast(sender, Thumb)
        Dim np As New Point(e.HorizontalChange, e.VerticalChange)
        np = np + GetLocate(t)
        Call SetLocate(t, np)
    End Sub

    '回転角度と拡大率を指定したTransformGroupを返す
    Private Function GetTransformGroup(angle As Double, scale As Double) As TransformGroup
        Dim tg As New TransformGroup
        tg.Children.Add(New RotateTransform(angle))
        tg.Children.Add(New ScaleTransform(scale, scale))
        Return tg
    End Function


    'Canvasを入れたTemplate付きのThumbを作成
    Private Function GetThumb() As Thumb
        Dim ct As New ControlTemplate
        ct.VisualTree = New FrameworkElementFactory(GetType(Canvas), "cc")

        Dim t As New Thumb
        t.Template = ct
        t.ApplyTemplate() 'Template再構成

        'Dim c As Canvas = t.Template.FindName("cc", t)
        'c.Background = Brushes.Transparent 'これをつけると透明部分でもドラッグ移動できる
        Return t
    End Function

    'Thumbを60度回転させて表示
    Private Sub AddThumbRotateThumb()
        Dim t As Thumb = GetThumb()
        Dim c As Canvas = t.Template.FindName("cc", t)
        Dim r As New Border With {
            .Background = Brushes.Cyan, .Width = 100, .Height = 100}
        Dim tb As New TextBlock With {.Text = "Thumbを60度回転"}
        t.Width = r.Width
        t.Height = r.Height
        c.Children.Add(r)
        c.Children.Add(tb)
        canvas1.Children.Add(t)
        SetLocate(t, New Point(50, 100))
        'Thumbを回転
        t.RenderTransform = GetTransformGroup(60, 1)
        t.RenderTransformOrigin = New Point(0.5, 0.5)
        AddHandler t.DragDelta, AddressOf ThumbDragDelta
    End Sub

    'Thumbの中のCanvasを60度回転させて表示
    Private Sub AddThumbRotateCanvas()
        Dim t As Thumb = GetThumb()
        Dim c As Canvas = t.Template.FindName("cc", t)
        Dim r As New Border With {
            .Background = Brushes.Cyan, .Width = 100, .Height = 100}
        Dim tb As New TextBlock With {
            .Text = "Thumbの中のCanvasを60度回転",
            .TextWrapping = TextWrapping.Wrap,
            .Width = r.Width}
        t.Width = r.Width
        t.Height = r.Height
        c.Children.Add(r)
        c.Children.Add(tb)
        canvas1.Children.Add(t)
        SetLocate(t, New Point(200, 100))
        Dim cc As Canvas = t.Template.FindName("cc", t)
        'Thumbの中のCanvasを回転
        cc.RenderTransform = GetTransformGroup(60, 1)
        cc.RenderTransformOrigin = New Point(0.5, 0.5)
        AddHandler t.DragDelta, AddressOf ThumbDragDelta
    End Sub

    'Thumbの中のCanvasの中のRectとtextBlockを60度回転させて表示
    Private Sub AddThumbRotateRect()
        Dim t As Thumb = GetThumb()
        Dim c As Canvas = t.Template.FindName("cc", t)
        Dim r As New Border With {
            .Background = Brushes.Cyan, .Width = 100, .Height = 100}
        Dim tb As New TextBlock With {
            .Text = "Thumbの中のCanvasの中のRectとtextBlockを60度回転",
            .TextWrapping = TextWrapping.Wrap,
            .Width = r.Width}
        t.Width = r.Width
        t.Height = r.Height
        c.Children.Add(r)
        c.Children.Add(tb)
        canvas1.Children.Add(t)
        SetLocate(t, New Point(350, 100))
        'Thumbの中のCanvasの中のRectとtextBlockを回転
        r.RenderTransform = GetTransformGroup(60, 1)
        r.RenderTransformOrigin = New Point(0.5, 0.5)
        tb.RenderTransform = GetTransformGroup(60, 1)
        tb.RenderTransformOrigin = New Point(0.5, 0.5)
        AddHandler t.DragDelta, AddressOf ThumbDragDelta
    End Sub

    Private Sub MainWindow_ContentRendered(sender As Object, e As EventArgs) Handles Me.ContentRendered
        'MsgBox("contentrendered!")
    End Sub


    Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
        Call AddThumbRotateThumb()
        Call AddThumbRotateCanvas()
        Call AddThumbRotateRect()

    End Sub
End Class
 
中の様子を見てみる
イメージ 4
この前の
Visual Studio 2015 Update 2をインストールした時の様子とXAMLのUIデバッグツールの表示の切り替え ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14151544.html
XAMLのUIデバッグツールってのを使って表示されているコントロールの大きさを
見ているところ、この機能面白いねえ
 
今回のコード
 
7年後、これならもっと楽にできそう?