Drag a drawing help required

bish

Member
Joined
Dec 30, 2008
Messages
14
Programming Experience
Beginner
If you run the code below it will only obviously drag the first drawing item only.

Can anyone help me modify this so l can...
1) Drag each 'x' independantly
2) i need 128 drawings so the array needs to be put into a loop.


VB.NET:
Public Class Form1
Dim letterbox As Rectangle() = {New Rectangle(10, 10, 15, 15), _
                                      New Rectangle(10, 30, 15, 15), _
                                      New Rectangle(10, 50, 15, 15)}

    Private dragOrigin As Point

    Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
        If Me.IsDragging(e) Then
            Me.dragOrigin = e.Location
        End If
    End Sub

    Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
        If Me.IsDragging(e) Then
            Me.Invalidate(Me.letterbox(0))
            Me.letterbox(0).Offset(e.X - Me.dragOrigin.X, e.Y - Me.dragOrigin.Y)
            Me.Invalidate(Me.letterbox(0))
            Me.dragOrigin = e.Location
        End If
    End Sub

    Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
        For a = 0 To 2
            e.Graphics.DrawString("X", Me.Font, Brushes.Black, Me.letterbox(a))
        Next a
    End Sub

    Private Function IsDragging(ByVal e As MouseEventArgs) As Boolean
        Return e.Button = Windows.Forms.MouseButtons.Left AndAlso Me.letterbox(0).Contains(e.Location)
    End Function

End Class

Hope there's someone out there that can put me out of my misery :)

Bish
 
You'll need to keep track of your Xs - ie which one is selected. In other words, in your MouseDown event, check which X you are over and save that information.
 
Thats what l am trying to do, but l cant seem to figure out which one is selected :(
Once l can get this figured, l could set up the relevant arrays or perhaps global attributes for the one that is selected.

Any help on how to figure which one is selected?
 
Play with this code that I just threw together - it needs tidying, but should give you some pointers.

VB.NET:
Option Explicit On
Option Strict On

Public Class Form1

    Public DrawnRectangleList As New List(Of DrawnRectangle)

    Public Sub New()

        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
        Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
        Me.SetStyle(ControlStyles.UserPaint, True)

        DrawnRectangleList.Add(New DrawnRectangle(100, 100, 100, 50))
        DrawnRectangleList.Add(New DrawnRectangle(200, 400, 200, 25))
        DrawnRectangleList.Add(New DrawnRectangle(300, 50, 50, 100))

    End Sub

    Public LastMousePosition As New Point(0, 0)
    Public SavedMousePosition As New Point(0, 0)
    Public MovingItem As Boolean = False

    Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
        MovingItem = False
        For Each _Box As DrawnRectangle In DrawnRectangleList
            _Box.Selected = False
            If _Box.HitTest(New Point(SavedMousePosition.X, SavedMousePosition.Y)) Then
                _Box.Selected = True
                MovingItem = True
            End If
        Next
        Me.Invalidate()
    End Sub

    Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
        If MovingItem = True AndAlso LastMousePosition.X <> e.X OrElse LastMousePosition.Y <> e.Y Then
            'mouse has moved
            For Each _Box As DrawnRectangle In DrawnRectangleList
                If _Box.Selected = True Then
                    _Box.Point = New Point(_Box.Point.X + (e.X - LastMousePosition.X), _Box.Point.Y + (e.Y - LastMousePosition.Y))
                    Exit For
                End If
            Next
        End If

        SavedMousePosition.X = e.X
        SavedMousePosition.Y = e.Y
        Me.Invalidate()
        LastMousePosition = SavedMousePosition
    End Sub

    Private Sub Form1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp
        MovingItem = False
        For Each _Box As DrawnRectangle In DrawnRectangleList
            _Box.Selected = False
        Next
        Me.Invalidate()
    End Sub

    Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
        With e.Graphics
            For Each _Box As DrawnRectangle In DrawnRectangleList
                If _Box.Selected = True Then
                    .FillRectangle(Brushes.Green, _Box.Point.X, _Box.Point.Y, _Box.Size.Width, _Box.Size.Height)
                ElseIf _Box.HitTest(New Point(SavedMousePosition.X, SavedMousePosition.Y)) AndAlso _Box.Selected = False Then
                    .FillRectangle(Brushes.Red, _Box.Point.X, _Box.Point.Y, _Box.Size.Width, _Box.Size.Height)
                End If
                .DrawRectangle(Pens.Black, _Box.Point.X, _Box.Point.Y, _Box.Size.Width, _Box.Size.Height)
            Next
        End With
    End Sub

End Class

Public Class DrawnRectangle

    Public Sub New(ByVal X As Integer, ByVal Y As Integer, ByVal Width As Integer, ByVal Height As Integer)
        _Point.X = X
        _Point.Y = Y
        _Size.Width = Width
        _Size.Height = Height
    End Sub

    Private _Selected As Boolean = False
    Public Property Selected() As Boolean
        Get
            Return _Selected
        End Get
        Set(ByVal value As Boolean)
            _Selected = value
        End Set
    End Property

    Private _Point As New Point
    Public Property Point() As Point
        Get
            Return _Point
        End Get
        Set(ByVal value As Point)
            _Point = value
        End Set
    End Property

    Private _Size As New Size
    Public Property Size() As Size
        Get
            Return _Size
        End Get
        Set(ByVal value As Size)
            _Size = value
        End Set
    End Property

    Public Function HitTest(ByVal pt As Point) As Boolean
        Using gp As New Drawing2D.GraphicsPath()
            gp.AddRectangle(New Rectangle(Me._Point.X, Me._Point.Y, Me._Size.Width, Me._Size.Height))
            Return gp.IsVisible(pt)
        End Using
    End Function

End Class
 
I need to identify each drawing as an individual.
What l mean is, imagine 128 squares all the same size, when you click on any square it brings up a number of 0 to 127 unique to that square.
This is going to be for a marching band so eventually each coordinates will be saved.

Hope this makes sense :)
 
The quickest way would be to add an ID property to the DrawnRectangle class, and change the New constructor to accept an ID value.
 
Ok this is how l have changed the 'New' method...
How do you mean 'constructor' ?

VB.NET:
    Public Sub New()
        Dim left As Integer
        Dim top As Integer
        Dim width As Integer
        Dim height As Integer
        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
        Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
        Me.SetStyle(ControlStyles.UserPaint, True)

        left = 10
        top = 10
        width = 10
        height = 10
        For a As Integer = 0 To 8
            DrawnRectangleList.Add(New DrawnRectangle(left, top, width, height))
            top = top + 20
        Next
    End Sub

Any help is greatly appreciated

Bish
 
Add the following to the DrawnRectangle class :-

VB.NET:
    Private _ID As integer = integer.MinValue
    Public Property ID() As integer
        Get
            Return _ID
        End Get
        Set(ByVal value As Integer)
            _ID = value
        End Set
    End Property

Now change :-

VB.NET:
    Public Sub New(ByVal X As Integer, ByVal Y As Integer, ByVal Width As Integer, ByVal Height As Integer)
        _Point.X = X
        _Point.Y = Y
        _Size.Width = Width
        _Size.Height = Height
    End Sub

to

VB.NET:
    Public Sub New(ByVal ID as Integer, ByVal X As Integer, ByVal Y As Integer, ByVal Width As Integer, ByVal Height As Integer)
        _ID = ID
        _Point.X = X
        _Point.Y = Y
        _Size.Width = Width
        _Size.Height = Height
    End Sub

so that, for every drawn rectangle you create, you need to give it an ID. You should then get an error on this line :-

VB.NET:
DrawnRectangleList.Add(New DrawnRectangle(left, top, width, height))

because you didnt give it the ID. Change it to :-

VB.NET:
DrawnRectangleList.Add(New DrawnRectangle(a, left, top, width, height))

So now every DrawnRectangle has a unique ID.
 
Just a thought, how easy would it be to 'Add a new class' and add
Public Class DrawnRectangle to it, can this be done and how would you call it?
 
Easy.

VB.NET:
Public Class AllDrawnItems

Public DrawnRectangles as new List (of DrawnRectangle)
Public DrawnCircles as new List (of DrawnCircle)

End Class

etc etc
 
l right clicked the project and added a new class and called it 'DrawnRectangle' then cut and copied the 'DrawnRectangle' code from 'Form1' and it worked :)
 
Back
Top