|
Draggable Rectangle Control
Published: 10/22/2008 |
|
Here's the beginnings of a user control that allows you to draw a rectangle on a form (add the control using Control.Add) that the user can then resize and move around the form as they see fit. There's plenty you can do to enhance the code - I wrote the control as a prototype to get someone started on making their own draggable / resizable rectangles.
VB:
' TODO: add a property for each of these settings...
Private m_ptMinSize As Point = New Point(25, 25)
Private m_boolAllowDrag As Boolean = True
Private m_boolAllowResize As Boolean = True
Private m_clrBorderColor As Color = Color.Black
' internal variables...
Private m_boolFocused As Boolean = False
Private m_boolDragging As Boolean = False
Private m_boolSizing As Boolean = False
Private m_crSizeType As Cursor = Cursors.Default
Private m_ptDragOffset As Point = New Point(0, 0)
Private Sub DraggableRectangle_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
If (m_boolAllowDrag) Then m_boolDragging = (Cursor = Cursors.Hand)
If m_boolAllowResize Then m_boolSizing = Not m_boolDragging
m_ptDragOffset = New Point(e.X, e.Y)
End Sub
Private Sub DraggableRectangle_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
' perform drag...
If m_boolDragging Then
Me.Top = Me.Top + (e.Y - m_ptDragOffset.Y)
Me.Left = Me.Left + (e.X - m_ptDragOffset.X)
Exit Sub
End If
' perform size...
If m_boolSizing Then
Select Case Cursor
Case Cursors.SizeNS
If e.Y >= m_ptMinSize.Y Then Me.Height = e.Y
Case Cursors.SizeWE
If e.X >= m_ptMinSize.X Then Me.Width = e.X
Case Else
If e.Y >= m_ptMinSize.Y Then Me.Height = e.Y
If e.X >= m_ptMinSize.X Then Me.Width = e.X
End Select
'redraw...
Me.Invalidate()
Exit Sub
End If
' alter cursor if not dragging or sizing...
If (e.X = Me.Width - 2 Or e.X = Me.Width - 3) And _
(e.Y = Me.Height - 2 Or e.Y = Me.Height - 3) Then
' bottom right corner...
Me.Cursor = Cursors.SizeNWSE
ElseIf (e.X = Me.Width - 2 Or e.X = Me.Width - 3) Then
' right side...
Me.Cursor = Cursors.SizeWE
ElseIf (e.Y = Me.Height - 2 Or e.Y = Me.Height - 3) Then
' bottom side...
Me.Cursor = Cursors.SizeNS
Else
Me.Cursor = Cursors.Hand
End If
End Sub
Private Sub DraggableRectangle_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp
m_boolDragging = False
m_boolSizing = False
End Sub
Private Sub DraggableRectangle_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.MouseEnter
m_boolFocused = True
Me.Invalidate()
End Sub
Private Sub DraggableRectangle_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.MouseLeave
m_boolFocused = False
Me.Invalidate()
End Sub
Private Sub DraggableRectangle_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
' draw borders...
' TODO: set pen color according to a property on the control...
Dim clsPen As Pen = New Pen(m_clrBorderColor, 1)
' set up pen appearance...
If m_boolFocused Then
clsPen.DashStyle = Drawing2D.DashStyle.Dash
Else
clsPen.DashStyle = Drawing2D.DashStyle.Solid
End If
' draw border...
e.Graphics.DrawRectangle(clsPen, New Rectangle(New Point(1, 1), New Size(Me.Size.Width - 2, Me.Size.Height - 2)))
End Sub
// TODO: add a property for each of these settings...
private Point m_ptMinSize = new Point(25, 25);
private bool m_boolAllowDrag = true;
private bool m_boolAllowResize = true;
private Color m_clrBorderColor = Color.Black;
// internal variables...
private bool m_boolFocused = false;
private bool m_boolDragging = false;
private bool m_boolSizing = false;
private Cursor m_crSizeType = Cursors.Default;
private Point m_ptDragOffset = new Point(0, 0);
private void DraggableRectangle_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (m_boolAllowDrag)
m_boolDragging = (Cursor == Cursors.Hand);
if (m_boolAllowResize)
m_boolSizing = ! m_boolDragging;
m_ptDragOffset = new Point(e.X, e.Y);
}
private void DraggableRectangle_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
// perform drag...
if (m_boolDragging)
{
this.Top = this.Top + (e.Y - m_ptDragOffset.Y);
this.Left = this.Left + (e.X - m_ptDragOffset.X);
return;
}
// perform size...
if (m_boolSizing)
{
if (Cursor == Cursors.SizeNS)
{
if (e.Y >= m_ptMinSize.Y)
this.Height = e.Y;
}
else if (Cursor == Cursors.SizeWE)
{
if (e.X >= m_ptMinSize.X)
this.Width = e.X;
}
else
{
if (e.Y >= m_ptMinSize.Y)
this.Height = e.Y;
if (e.X >= m_ptMinSize.X)
this.Width = e.X;
}
//redraw...
this.Invalidate();
return;
}
// alter cursor if not dragging or sizing...
if ((e.X == this.Width - 2 | e.X == this.Width - 3) & (e.Y == this.Height - 2 | e.Y == this.Height - 3))
{
// bottom right corner...
this.Cursor = Cursors.SizeNWSE;
}
else if (e.X == this.Width - 2 | e.X == this.Width - 3)
{
// right side...
this.Cursor = Cursors.SizeWE;
}
else if (e.Y == this.Height - 2 | e.Y == this.Height - 3)
{
// bottom side...
this.Cursor = Cursors.SizeNS;
}
else
this.Cursor = Cursors.Hand;
}
private void DraggableRectangle_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
m_boolDragging = false;
m_boolSizing = false;
}
private void DraggableRectangle_MouseEnter(object sender, System.EventArgs e)
{
m_boolFocused = true;
this.Invalidate();
}
private void DraggableRectangle_MouseLeave(object sender, System.EventArgs e)
{
m_boolFocused = false;
this.Invalidate();
}
private void DraggableRectangle_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
// draw borders...
// TODO: set pen color according to a property on the control...
Pen clsPen = new Pen(m_clrBorderColor, 1F);
// set up pen appearance...
if (m_boolFocused)
clsPen.DashStyle = Drawing2D.DashStyle.Dash;
else
clsPen.DashStyle = Drawing2D.DashStyle.Solid;
// draw border...
e.Graphics.DrawRectangle(clsPen, new Rectangle(new Point(1, 1), new Size(this.Size.Width - 2, this.Size.Height - 2)));
}
If you use the C# version of the above code, don't forget to add the event handler hook code to the Initialize event of the control.
Questions or Comments? .
VB to C# and C# to VB translation provided by Instant C# and Instant VB.