I'm currently making a node diagram control for Winforms, the control inherits from the Container class. The control can contain nodes, and a node is basically just an "empty" class with properties, so nodes are handled by the control (drawn, moved, etc).
My control needs to support zooming and panning. Currently I'm zooming by using the Graphics.ScaleTransform method, and panning by using AutoScroll.
The two work great by themselves, but using them together doesn't work.
To make panning "better", I have hidden the scrollbars, set the AutoScrollMinSize to 9000 and centered the AutoScrollPosition (4500). So that it hopefully feels like you have a canvas to work on, so that you can go any direction that you'd like.
That works quite well, however when zooming (ScaleTransform), the nodes will be moved x amount to the left top corner of the form (if zooming out) or to the right bottom corner (if zooming in).
Youtube video of problem: https://www.youtube.com/watch?v=uJBAHtNhung
Custom control OnPaint:
G.TranslateTransform(AutoScrollPosition.X, AutoScrollPosition.Y)
G.ScaleTransform(Zoom, Zoom)
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
For Each Connection As Connection In Connections
Connection.Draw(G)
Next
For Each Node As Node In Nodes
Node.Draw(G)
Next
If ActiveTool IsNot Nothing Then
ActiveTool.OnDraw(G)
End If
Zoom:
If e.Delta < 0 Then
NodeContainer.Zoom -= 0.1F
Else
NodeContainer.Zoom += 0.1F
End If
Pan:
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
How would I got about solving this, or should I be going about this a different way (maybe draw an image instead, and then reposition that image, etc.)?
Here's a link to the whole solution so that you can go through the code and toy around with it.
Download Me Via DropBox
And no, it's not the prettiest at the moment, but I'm just trying to get it functional atm.
Best regards