首页 文章

VB赢得自定义控制缩放和平移功能?

提问于
浏览
0

我目前正在为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

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

1 回答

  • 0

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

    放大:

    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)
    

相关问题