【问题标题】:VB winforms custom control zoom and pan functionality?VB winforms 自定义控件缩放和平移功能?
【发布时间】:2015-12-13 15:32:39
【问题描述】:

我目前正在为 Winforms 制作一个节点图控件,该控件包含的节点基本上只是一个具有属性的“空”类,因此在控件中绘制节点并由控件处理它们。

我的控件需要支持缩放和平移。目前我正在使用 Graphics.ScaleTransform 方法进行缩放,并使用 AutoScroll 进行平移。

这两个单独使用效果很好,但是一起使用就不行了。

为了使平移“更好”,我隐藏了滚动条,将 AutoScrollMinSize 设置为 9000 并将 AutoScrollPosition (4500) 居中。因此,希望您感觉就像有一块画布可以工作,这样您就可以朝着任何您喜欢的方向前进。

效果很好,但是在缩放 (ScaleTransform) 时,节点将移动 x 量到窗体的左上角(如果缩小)或右下角(如果放大)。

Youtube视频问题:https://www.youtube.com/watch?v=uJBAHtNhung

因此,由于 stackoverflow 上的文本长度问题,我无法发布所有代码,所以我将尝试发布相关内容(我想我还是应该这样做)。

自定义控件 OnPaint:

    G.TranslateTransform(AutoScrollPosition.X, AutoScrollPosition.Y)

    G.ScaleTransform(Zoom, Zoom)

    'Draw grid
    If ShowGrid Then
        Using Pen As New Pen(GridColor.ToBrush())
            For row As Integer = 0 To viewportRect.Right Step GridSize.Width
                G.DrawLine(Pen, New Point(row, 0), New Point(row, 0 + viewportRect.Bottom))
            Next

            For col As Integer = 0 To viewportRect.Bottom Step GridSize.Height
                G.DrawLine(Pen, New Point(0, col), New Point(0 + viewportRect.Right, col))
            Next
        End Using
    End If

    'Draw connections
    For Each Connection As Connection In Connections
        Connection.Draw(G)
    Next

    'Draw all the nodes
    For Each Node As Node In Nodes
        Node.Draw(G)
    Next

    'Draw the active tool (Multi select or NodeLinker)
    If ActiveTool IsNot Nothing Then
        ActiveTool.OnDraw(G)
    End If

缩放:

If e.Delta < 0 Then
    NodeContainer.Zoom -= 0.1F
Else
    NodeContainer.Zoom += 0.1F
End If

潘:

  If Panning Then
            Delta = New Point(StartPoint.X - e.X, StartPoint.Y - e.Y)
            NodeContainer.AutoScrollPosition = New Point(Delta.X - NodeContainer.AutoScrollPosition.X, Delta.Y - NodeContainer.AutoScrollPosition.Y)
        End If

我将如何解决这个问题,或者我应该以不同的方式解决这个问题(也许改为绘制图像,然后重新定位该图像等)?

【问题讨论】:

  • 通常的方法是使用两个面板,外层(父)是自动滚动的,内层(嵌套)是你绘制的。通常内部是一个 PictureBox..

标签: c# vb.net winforms custom-controls gdi+


【解决方案1】:

答案是移除自动滚动,然后在发生缩放或平移时重新定位所有节点。

缩放:

oldZoom = NodeContainer.Zoom

If e.Delta < 0 Then
    NodeContainer.Zoom = Math.Max(NodeContainer.Zoom - 0.1F, 0.01F)
Else
    NodeContainer.Zoom = Math.Min(NodeContainer.Zoom + 0.1F, 10.0F)
End If

For Each Node As Node In NodeContainer.Nodes
    oldZoomLocation = New Point(e.X / oldZoom, e.Y / oldZoom)
    newZoomLocation = New Point(e.X / NodeContainer.Zoom, e.Y / NodeContainer.Zoom)

    Node.Location = New Point(newZoomLocation.X - oldZoomLocation.X + Node.Location.X, newZoomLocation.Y - oldZoomLocation.Y + Node.Location.Y)
Next

潘:

Delta = New Point(e.X - StartPoint.X, e.Y - StartPoint.Y)

For Each Node As Node In NodeContainer.Nodes
    Node.Location = New Point(Node.Location.X + (Delta.X / NodeContainer.Zoom), Node.Location.Y + (Delta.Y / NodeContainer.Zoom))
Next

StartPoint = New Point(e.X, e.Y)

【讨论】:

    猜你喜欢
    • 2021-10-15
    • 1970-01-01
    • 2015-07-15
    • 2011-01-04
    • 1970-01-01
    • 1970-01-01
    • 2018-03-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多