Reputation: 1474
I'm developing a console where I want to drag a button to a grid:
To drag the button, I use the following procedure:
Public drag As Boolean = False
Public ptX As Integer = 0
Public ptY As Integer = 0
Public btn As Button
Private Sub MoveButton_MouseDown(sender As Object, e As MouseEventArgs) Handles MoveButton.MouseDown
drag = True
btn = CType(sender, Button)
ptX = e.X : ptY = e.Y
End Sub
Private Sub MoveButton_MouseMove(sender As Object, e As MouseEventArgs) Handles MoveButton.MouseMove
If drag Then
btn.Location = New Point(btn.Location.X + e.X - ptX, btn.Location.Y + e.Y - ptY)
Me.Refresh()
End If
End Sub
Private Sub MoveButton_MouseUp(sender As Object, e As MouseEventArgs) Handles MoveButton.MouseUp
drag = False
End Sub
So far, so good! This works fine for that matter. However, I'm trying to highlight the cell while hoovering the button on it like this:
To do so, I tried to do the following:
Private Sub CellA1_MouseHover(sender As Object, e As EventArgs) Handles CellA1.MouseHover
If drag Then
CellA1.BackColor = Color.Red
End If
End Sub
Of course I can't do that, unless I, somehow, enable the CellA1.MouseHover
event while dragging the MoveButton
.
Can anyone help me with this?
If, however, you're having a struggling will to help me further, my last goal is to place the MoveButton
on the red cell place:
But feel free to don't help me at all with this part of the procedure since I have no code to perform this yet. Any help will be very appreciated. And, as always, thank you all in advance.
Upvotes: 1
Views: 274
Reputation: 18310
Since your mouse is not actually on the PictureBox
when you drag the button it will never raise any mouse events. What you can do instead is to call the GetChildAtPoint()
method of your form to get the control behind the button. Once you have that just verify that the name starts with "Cell" and change the back color.
To snap to the cell's location you'll need to indicate to MouseUp
which cell we're currently at. Simply store the cell control in a variable and you can then just set yourButton.Location = currentCell.Location
Here are the changes I've made to your code, commented for clarity:
Public drag As Boolean = False
Public ptX As Integer = 0
Public ptY As Integer = 0
Public btn As Button
Public prevCtrl As Control = Nothing 'Store the previous Cell the button was dragged over.
' We need this to be able to reset the BackColor of the Cell,
' and also so that you can snap to its location once you drop the button.
Private Sub MoveButton_MouseDown(sender As Object, e As MouseEventArgs) Handles MoveButton.MouseDown
'No changes made here.
drag = True
btn = CType(sender, Button)
ptX = e.X : ptY = e.Y
End Sub
Private Sub MoveButton_MouseMove(sender As Object, e As MouseEventArgs) Handles MoveButton.MouseMove
If drag Then
btn.Location = New Point(btn.Location.X + e.X - ptX, btn.Location.Y + e.Y - ptY)
'Go 1 pixel up, or else GetChildAtPoint() will return the button instead of the control behind it.
Dim LookPoint As Point = Point.Subtract(btn.Location, New Size(0, 1))
'Get the control located below/behind the button.
Dim ControlBelow As Control = Me.GetChildAtPoint(LookPoint, GetChildAtPointSkip.Invisible Or GetChildAtPointSkip.Disabled) 'Ignore invisible or disabled controls.
'Check so that the previous cell is not also the current cell. If they're the same then we won't change anything.
If prevCtrl IsNot ControlBelow Then
'Ok, the current cell and the previous cell are not the same.
'Now check if there was any previous cell at all.
If prevCtrl IsNot Nothing Then
'There was a previous cell, but since the button
'is no longer hovering over it we reset its BackColor.
prevCtrl.BackColor = Color.White
prevCtrl = Nothing
End If
'Check that there infact is a control behind the button,
'and also check that its name starts with "Cell".
If ControlBelow IsNot Nothing AndAlso ControlBelow.Name.StartsWith("Cell", StringComparison.OrdinalIgnoreCase) Then
'The control behind the button is a valid Cell. Change its BackColor.
ControlBelow.BackColor = Color.Red
prevCtrl = ControlBelow 'The previous cell is now the current cell.
End If
End If
'Me.Refresh() - this is a very unnecessary call, it will just eat CPU. The form does not need to be redrawn at this point.
End If
End Sub
Private Sub MoveButton_MouseUp(sender As Object, e As MouseEventArgs) Handles MoveButton.MouseUp
'Check if we dragged the button. At this point prevCtrl is the current cell (if it's not Nothing).
If drag = True AndAlso prevCtrl IsNot Nothing Then
btn.Location = prevCtrl.Location 'Snap to the cell's location.
prevCtrl.BackColor = Color.White 'Reset the cell's BackColor.
prevCtrl = Nothing 'Reset this since we're no longer dragging the button.
End If
drag = False
End Sub
And it works like a charm!
Upvotes: 2