Quantcast
Channel: 午後わてんのブログ
Viewing all articles
Browse latest Browse all 420

WPFとVB.NET、エクセルのグループ化を真似したいからまずはグループ化のRectを取得

$
0
0

グループ化するときに必要なRectを取得する
グループ化ってのはエクセルの図形とかをグループ化っての、あれをどうしても真似したい

イメージ 1
赤枠が必要なRectで対象になるコントロールがぴったり収まる四角形



デザイン画面とXAML
イメージ 2
DockPanelに
bt1って名前をつけたButtonと
canvas1って名前をつけたCanvasを配置しただけ
StatusBarはあんまり関係ないしDockPanelもあんまり意味ないな

VBコード
イメージ 3

Imports System.Windows.Controls.Primitives


Class MainWindow
    Private thumbList As New List(Of Thumb)
    Private waku As Path '枠


    'Thumbをcanvas1に追加表示
    Private Sub AddThumb(p As Point, s As Size, angle As Double)
        Dim t As New Thumb
        With t
            .Width = s.Width
            .Height = s.Height
            .RenderTransform = New RotateTransform(angle)
        End With
        Call SetLocate(t, p)
        thumbList.Add(t)
        canvas1.Children.Add(t)
        AddHandler t.DragDelta, AddressOf ThumbDragDelta

    End Sub

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

    'Thumbの座標ゲット
    Private Function GetLocate(t As Thumb) As Point
        Return New Point(Canvas.GetLeft(t), Canvas.GetTop(t))
    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


    '渡されたThumbがぴったり収まるRectを返す
    Private Function GetRect(t As Thumb) As Rect
        Dim gt As GeneralTransform = t.TransformToVisual(canvas1)
        Dim r As Rect = gt.TransformBounds(
            New Rect(New Point(0, 0), New Size(t.Width, t.Height)))
        Return r
    End Function

    '渡されたThumbすべてがぴったり収まるRectを返す
    'RectのUnionメソッドを使う
    Private Function GetUnionRect(thumbList As List(Of Thumb)) As Rect
        Dim r As New Rect
        Dim ur As New Rect 'すべてのRectがぴったり収まるRect用
        Dim rl As New List(Of Rect) '左上座標取得用
        For Each t As Thumb In thumbList
            r = GetRect(t)
            rl.Add(r)
            ur.Union(r)
        Next
        Dim p As Point = GetLeftTop(rl) '左上座標取得
        ur.Location = ur.Location + p '座標変更
        'サイズ変更
        ur.Size = New Size(ur.Width - p.X, ur.Height - p.Y)
        Return ur

    End Function

    '複数Rectの一番左上取得
    Private Function GetLeftTop(rectList As List(Of Rect)) As Point
        Dim x As Double = rectList(0).X
        Dim y As Double = rectList(0).Y
        For i As Integer = 1 To rectList.Count - 1
            x = Math.Min(x, rectList(i).X)
            y = Math.Min(y, rectList(i).Y)
        Next
        Return New Point(x, y)
    End Function


    '赤枠描画
    Private Sub DrawRectPath(r As Rect)
        '前回の枠があったら消す
        If waku IsNot Nothing Then
            canvas1.Children.Remove(waku)
        End If
        '新しい赤枠描画
        Dim p As New Path With {.Stroke = Brushes.Red, .StrokeThickness = 1}
        Dim g As New RectangleGeometry(r)
        p.Data = g
        canvas1.Children.Add(p)
        waku = p
    End Sub



    'アプリ起動直後、Thumbを表示する
    Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
        Call AddThumb(New Point(80, 10), New Size(100, 100), 10)
        Call AddThumb(New Point(180, 50), New Size(50, 100), 30)
        Call AddThumb(New Point(200, 100), New Size(120, 100), 20)
    End Sub


    'グループ化した場合のRect表示
    Private Sub bt1_Click(sender As Object, e As RoutedEventArgs) Handles bt1.Click
        Dim ur As Rect = GetUnionRect(thumbList)
        Call DrawRectPath(ur)
    End Sub

End Class



イメージ 4
1個目のRect

イメージ 5
2個目

イメージ 6
3個め

3つの青枠から全体のRect(水色枠)を取得
イメージ 7
RectのUnionメソッドを使って全体のRectを取得

左上座標取得
イメージ 8
3つの青枠の中で一番上と一番左になる座標を取得、地道にMath.MinをFor Nextで回している

左上座標変更
イメージ 9
左上座標を(0,0)から(62,10)へ変更

イメージ 10
移動した分だけサイズも変更でぴったり収まる枠Rectが取得完了

目印の赤枠表示
イメージ 11
Pathを使って赤枠表示

書いている途中で思ったのが要は左上と右下になる座標がわかればいいんだからUnionメソッドを使わないで
左上座標をMath.Min求めるついでにMath.Maxも使って右下座標も求めたらいいんじゃないかってこと



Canvasを入れたControlTemplateをThumbのTemplateに指定して
Canvasの中にImageを配置
Thumb
┗Canvas
┗Image
こんな感じにしておいて、複数のThumbををグループ化したい
今のPixtack紫陽花2ndは
Thumb
┗Image
になっているからそのままだとグループ化できないっぽい

Thumb
┗Canvas
┣Image
┗Path
とかできるようにしたい

グループ化した時は
Thumb
┗Canvas
┣Thumb
┗Canvas
┣Image
┗Image
┗Thumb
┗Canvas
┣Image
┣Path
┗Image
こんな感じになればいいのかなあ


今回のコード






Viewing all articles
Browse latest Browse all 420

Trending Articles