Я предлагаю немного другой метод для вычисления текущей позиции курсора, когда отношение применяется к размерам прямоугольника.
Конечно, вам нужно сохранить начальную позицию прямоугольника, используя событие MouseDown элемента управления, а затем отслеживать движения мыши, используя событие MouseMove.
Текущая позиция курсора рассчитывается как обычно (смена текущей позиции курсора и начальной позиции, когда смещения отрицательны).
Единственная разница - это высота прямоугольника, когда общий размер зависит от отношения Ratio.
В этом случае Rectangle.Location.Y
определяется Rectangle.Width / Ratio
мера.Это становится видимым, если Cursor.Location.Y
на выше начальной позиции (Cursor.Location.Y <= StartingPosition.Y
).Так же, как в коде, который вы опубликовали.
Например, я использую пользовательский класс Rectangle, который содержит всю информацию, необходимую для рисования фигуры, с определенным соотношением или без него, примененным к его размерам.
Обратите внимание, что Ratio
жестко задан в 1.6
: это просто для тестирования, конечно, он может быть установлен на что-то еще.
Визуальный образец результатов:
Private DrawingRects As List(Of DrawingRectangle) = New List(Of DrawingRectangle)()
Private Sub PicureBox1_MouseDown(sender As Object, e As MouseEventArgs) Handles PicureBox1.MouseDown
If e.Button = MouseButtons.Left Then
DrawingRects.Add(New DrawingRectangle() With {
.DrawingcColor = Color.LightGreen,
.Location = e.Location,
.Owner = CType(sender, Control),
.Ratio = 1.6,
.Size = Size.Empty,
.StartPosition = e.Location
})
End If
End Sub
Private Sub PicureBox1_MouseMove(sender As Object, e As MouseEventArgs) Handles PicureBox1.MouseMove
If e.Button = MouseButtons.Left Then
Dim rect As DrawingRectangle = DrawingRects.Last()
If e.X < rect.StartPosition.X Then rect.Location = New Point(e.X, rect.Location.Y)
If e.Y < rect.StartPosition.Y Then rect.Location = New Point(rect.Location.X, e.Y)
Dim currentWidth As Integer = Math.Abs(rect.StartPosition.X - e.X)
If rect.Ratio = 1.0F Then
rect.Size = New Size(currentWidth, Math.Abs(rect.StartPosition.Y - e.Y))
Else
If rect.StartPosition.Y <= rect.Location.Y Then
rect.Size = New Size(currentWidth, CType(Math.Abs(rect.StartPosition.X - e.X) / rect.Ratio, Integer))
Else
Dim currentHeight As Integer = CType(currentWidth / rect.Ratio, Integer)
rect.Location = New Point(rect.Location.X, rect.StartPosition.Y - currentHeight)
rect.Size = New Size(currentWidth, currentHeight)
End If
End If
DrawingRects(DrawingRects.Count - 1) = rect
DirectCast(sender, Control).Invalidate()
End If
End Sub
Private Sub PicureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PicureBox1.Paint
Dim canvas As Control = DirectCast(sender, Control)
If DrawingRects.Count > 0 Then
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias
For Each rect As DrawingRectangle In DrawingRects
If canvas IsNot rect.Owner Then Continue For
Using pen As New Pen(rect.DrawingcColor, rect.PenSize)
e.Graphics.DrawRectangle(pen, New Rectangle(rect.Location, rect.Size))
End Using
Next
End If
End Sub
Класс DrawingRectangle
:
Примечание: класс имеет свойство Owner
, ссылающееся на текущий элемент управления, на котором нарисована форма: это позволяет использовать List(Of DrawingRectangle)
с различными элементами управления нав то же время.
Public Class DrawingRectangle
Private rectAspect As SizeF = SizeF.Empty
Private rectRatio As Single = 0F
Public Property Owner As Control
Public Property Location As Point
Public Property Size As Size
Public Property StartPosition As Point
Public Property DrawingcColor As Color
Public Property PenSize As Single
Public Property Aspect() As SizeF
Get
Return rectAspect
End Get
Set(ByVal value As SizeF)
Me.rectAspect = value
SetAspectRatio(value)
End Set
End Property
Public Property Ratio As Single
Get
Return rectRatio
End Get
Set(ByVal value As Single)
rectRatio = value
SetAspectRatio(value)
End Set
End Property
Private Sub SetAspectRatio(aspect As SizeF)
Me.rectRatio = aspect.Width / aspect.Height
End Sub
Private Sub SetAspectRatio(ratio As Single)
Me.rectAspect = New SizeF(100, 100 / ratio)
End Sub
End Class