这是我找到此网站后的第一个问题。
我目前正在尝试创建一个VB.NET用户控件,该控件包含一个面板,在该面板上一些 在Paint事件期间应绘制图形对象(圆形,矩形,直线)。 可以简化面板始终为正方形(宽度=高度)的情况。 不幸的是,使用图片框进行绘制不是我的选择。我也不要 使用自动滚动并具有可见的滚动条。
该面板应可由用户平移/缩放。平移应通过按 鼠标中键和缩放应通过滚动鼠标滚轮来完成。 我已经找到了很好的示例,说明如何实现这些功能,到目前为止,它们都有效 很好。 现在,我还想添加用户应该能够缩放到特定位置的功能 面板的(正方形)区域,由他按下时显示的选择矩形 按下鼠标左键时,鼠标左键的大小会调整 左键。 (这应该是类似的行为,例如,放大到PDF文档)。 这是我被卡住的原因。
我提取了负责面板及其事件的代码部分, 这是我到目前为止的内容:
Public Class Form1
Private zoomstart as Point
Private zoomfirst as Point
Private zoomwidth as Integer
Private zoomrect as Rectangle
Private WithEvents tmrMarch as New Timer
Private MarchOffset as Integer = 0
Private OffsetDelta as Integer = 2
Private DashPattern() as Single = {5,5}
Private zoom As Single = 1.0
Private startx as Integer = 0
Private starty as Integer = 0
Private offsetx as Integer = 0
Private offsety as Integer = 0
Private mouseDownPt as Point
Private initialwidth As Integer
Public WithEvents Canvas1 As New Canvas
Private Enum T_Mouseaction
Rectanglezooming
Wheelzooming
Panning
None
End Enum
Private Mouseaction As T_Mouseaction = T_Mouseaction.None
Private Sub Form1_Load(ByVal sender As System.Object,ByVal e As System.EventArgs) Handles MyBase.Load
Canvas1.Size = New Size(Me.ClientSize.Width,Me.ClientSize.Width)
Canvas1.AutoScroll = False
initialwidth = Canvas1.Width
Me.Controls.Add(Canvas1)
End Sub
Private Sub Canvas1_Paint(ByVal sender As Object,ByVal e As PaintEventArgs) Handles Canvas1.Paint
Select Case Mouseaction
Case T_Mouseaction.None
e.Graphics.TranslateTransform(offsetx,offsety)
e.Graphics.ScaleTransform(zoom,zoom)
Case T_Mouseaction.Panning
e.Graphics.TranslateTransform(offsetx,zoom)
Case T_Mouseaction.Rectanglezooming
e.Graphics.TranslateTransform(offsetx,zoom)
Case T_Mouseaction.Wheelzooming
e.Graphics.ScaleTransform(zoom,zoom)
e.Graphics.TranslateTransform(offsetx,offsety)
End Select
Call DrawImage(e.Graphics)
e.Graphics.ResetTransform
If Mouseaction = T_Mouseaction.Rectanglezooming Then
MarchOffset = MarchOffset + OffsetDelta
Dim pen as New Pen(Color.Black,2)
pen.DashPattern = DashPattern
pen.DashOffset = MarchOffset
pen.Color = Color.Red
e.Graphics.DrawRectangle(pen,zoomrect)
End If
End Sub
Private Sub DrawImage(ByVal gr As Graphics)
Dim rect As Rectangle
rect = New Rectangle(0,initialwidth,initialwidth)
gr.FillEllipse(brushes.LightGreen,rect)
gr.DrawEllipse(Pens.Green,rect)
rect = New Rectangle(0.375 * initialwidth,0.375 * initialwidth,0.25 * initialwidth,0.375 * initialwidth)
gr.FillEllipse(brushes.LightBlue,rect)
gr.DrawEllipse(Pens.Blue,rect)
rect = New Rectangle(0.1875 * initialwidth,0.625 * initialwidth,0.625 * initialwidth)
gr.DrawArc(Pens.Red,rect,20,140)
rect = New Rectangle(0.1875 * initialwidth,0.1875 * initialwidth,0.25 * initialwidth)
gr.FillEllipse(brushes.White,rect)
gr.DrawEllipse(Pens.Black,rect)
rect = New Rectangle(0.25 * initialwidth,0.125 * initialwidth,0.125 * initialwidth)
gr.FillEllipse(brushes.Black,rect)
rect = New Rectangle(0.625 * initialwidth,rect)
rect = New Rectangle(0.6875 * initialwidth,rect)
End Sub
Private Sub tmrMarch_Tick(ByVal sender as Object,ByVal e as EventArgs) Handles tmrMarch.Tick
Canvas1.Refresh
End Sub
Private Sub Canvas1_MouseDown(ByVal sender As Object,ByVal e As MouseEventArgs) Handles Canvas1.MouseDown
If e.Button = Windows.Forms.MouseButtons.Middle Then
Mouseaction = T_Mouseaction.Panning
mouseDownPt = e.Location
startx = offsetx
starty = offsety
End If
If e.Button = Windows.Forms.MouseButtons.Left Then
zoomstart = e.Location
tmrMarch.Interval = 100
tmrMarch.Enabled = True
End If
End Sub
Private Sub Canvas1_MouseUp(ByVal sender As Object,ByVal e As MouseEventArgs) Handles Canvas1.MouseUp
Cursor = Cursors.Default
tmrMarch.Enabled = False
If Mouseaction = T_Mouseaction.Rectanglezooming Then
Dim oldzoom as Single = zoom
zoom = 1 ' <=== ?
zoom = Math.Truncate(zoom / 0.2) * 0.2
Dim oldoffsetx,oldoffsety as Integer
Dim newoffsetx,newoffsety as Integer
oldoffsetx = CInt(zoomrect.X / oldzoom)
oldoffsety = CInt(zoomrect.Y / oldzoom)
newoffsetx = CInt(zoomrect.X / zoom)
newoffsety = CInt(zoomrect.Y / zoom)
offsetx = newoffsetx - oldoffsetx + offsetx ' <=== ?
offsety = newoffsety - oldoffsety + offsety ' <=== ?
End If
Mouseaction = T_Mouseaction.None
Canvas1.Refresh
End Sub
Private Sub Canvas1_MouseMove(ByVal sender As Object,ByVal e As MouseEventArgs) Handles Canvas1.MouseMove
If e.Button = Windows.Forms.MouseButtons.Middle
Cursor = Cursors.Hand
Dim mousePosnow as Point = e.Location
Dim deltaX,deltaY as Integer
deltaX = mousePosnow.X - mouseDownPt.X
deltaY = mousePosnow.Y - mouseDownPt.Y
offsetx = CInt(startx + deltaX)
offsety = CInt(starty + deltaY)
Mouseaction = T_Mouseaction.Panning
Canvas1.Refresh
End If
If e.Button = Windows.Forms.MouseButtons.Left Then
Dim loc as Point
loc = e.Location
Dim sizex,sizey as Integer
sizex = Math.Abs(zoomstart.X - loc.X)
sizey = Math.Abs(zoomstart.Y - loc.Y)
zoomwidth = Math.Max(sizex,sizey)
If loc.X < zoomstart.X Then
zoomfirst.X = loc.X
Else
zoomfirst.X = zoomstart.x
End If
If loc.Y < zoomstart.Y Then
zoomfirst.Y = loc.Y
Else
zoomfirst.Y = zoomstart.Y
End If
If zoomwidth > 10 Then
Mouseaction = T_Mouseaction.Rectanglezooming
End If
zoomrect = New Rectangle(zoomfirst,New Size(zoomwidth,zoomwidth))
Canvas1.Refresh
End If
End Sub
Private Sub Canvas1_MouseWheel(ByVal sender as Object,ByVal e as MouseEventArgs) Handles Canvas1.MouseWheel
If Mouseaction = T_Mouseaction.Panning Then
Exit Sub
End If
Dim oldzoom as Single = zoom
If e.Delta > 0 Then
zoom = zoom + 0.2
End If
If e.Delta < 0 Then
zoom = Math.Max(zoom - 0.2,0.2)
End If
Dim mousePosnow as Point = e.Location
Dim x,y as Integer
x = mousePosnow.X
y = mousePosnow.Y
Dim oldoffsetx,oldoffsety as Integer
Dim newoffsetx,newoffsety as Integer
oldoffsetx = CInt(x / oldzoom)
oldoffsety = CInt(y / oldzoom)
newoffsetx = CInt(x / zoom)
newoffsety = CInt(y / zoom)
offsetx = newoffsetx - oldoffsetx + offsetx
offsety = newoffsety - oldoffsety + offsety
Mouseaction = T_Mouseaction.Wheelzooming
Canvas1.Refresh
End Sub
Private Sub Canvas1_MouseEnter(ByVal sender as Object,ByVal e as EventArgs) Handles Canvas1.MouseEnter
Canvas1.Focus
End Sub
Private Sub Canvas1_MouseLeave(ByVal sender as Object,ByVal e as EventArgs) Handles Canvas1.MouseLeave
Me.Focus
End Sub
End Class
Public Class Canvas
Inherits Panel
Public Sub New
Me.DoubleBuffered = True
End Sub
End Class
请向Rod Stephens索取笑脸代码,在这种情况下,该代码只是一个占位符 以便稍后在用户控件中绘制图形。 (http://csharphelper.com/blog/2014/11/scale-a-drawing-so-it-fits-a-target-area-in-c/)
在MouseMove事件中已经正确创建了缩放矩形(行进蚂蚁)。 在MouseUp事件中,我要应用缩放并将选定区域缩放为大小 面板的。在Paint事件中,实际缩放由ScaleTransform和 TranslateTransform操作。
但是我不知道如何计算适当的缩放系数和x / y偏移量,因此 所选区域将缩放为面板尺寸。我试图定位用于以下代码 鼠标滚轮缩放。我有点困惑,因为在我看来 实际上涉及两个缩放因子:一个受鼠标滚轮操作影响 另一个链接到选择矩形操作。 我还尝试将缩放系数计算为“ selection.width / panel.width”, 但这只会给面板导航带来“跳跃”的行为,并且无法正确缩放。
任何帮助将不胜感激。预先非常感谢。