You need to handle the drag-and-drop-related events of the controls on the Panel too.
Printable View
You need to handle the drag-and-drop-related events of the controls on the Panel too.
Yes Indeed but how?
I add the panels dynamically. They are not there static like the form.
I have tried the code below but It doesnt do it.
Neither do i think it carries some logic.
VB Code:
Friend WithEvents pnl As System.Windows.Forms.Panel Private Sub Addlabel() lbl = New Label pnl.Controls.Add(lbl) AddHandler lbl.MouseDown, AddressOf lableEventHandler lbl.Location = New Point(24, 21) lbl.Size = New Size(111, 98) pnl.AllowDrop = True lbl.Text = Me.RichTextBox1.Text End Sub Private Sub lblDragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles pnl.DragDrop If e.Data.GetDataPresent(GetType(Label)) Then lbl = DirectCast(e.Data.GetData(GetType(Label)), Label) End If End Sub Private Sub lblDragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles pnl.DragEnter If e.Data.GetDataPresent(GetType(Label)) Then e.Effect = DragDropEffects.Move Else e.Effect = DragDropEffects.None End If End Sub Private Sub lableEventHandler(ByVal sender As Object, ByVal eMap As System.Windows.Forms.MouseEventArgs) lbl = CType(sender, Label) lbl.DoDragDrop(lbl, DragDropEffects.Move) End Sub
My problem here is that, if we handle the drag-and-drop-related events of the controls on the Panel, we will be like we are dragging the controls over the panel and not in relation to the mainform.
I was thinking that instead of using a panel, i would simply use a label it-self, but the main constraint i see is that i cant easily set the margins for the text.
What do you think!
I think it doesn't matter what object you are over when the MouseDown event is raised. If you pass the Panel to the first argument of DoDragDrop then it's the Panel that you'll be dragging and it's the Panel that will be returned to you from e.Data when the DragDrop event is raised. At that point what control you originally moused down on is immaterial and forgotten.
What am i getting wrong with this?
VB Code:
Private Sub Addlabel() lbl = New Label pnl.Controls.Add(lbl) AddHandler lbl.MouseDown, AddressOf lableEventHandler lbl.Location = New Point(24, 21) lbl.Size = New Size(111, 98) 'pnl.AllowDrop = True lbl.Text = Me.RichTextBox1.Text End Sub 'DragDrop event for the control where the drop will occur, use the GetData method to retrieve the data being dragged Private Sub lblDragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Me.DragDrop If e.Data.GetDataPresent(GetType(Panel)) Then pnl = DirectCast(e.Data.GetData(GetType(Panel)), Panel) End If End Sub Private Sub lblDragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Me.DragEnter 'Ensure that the data being dragged is of an acceptable type (in this case, Panel). If e.Data.GetDataPresent(GetType(Panel)) Then e.Effect = DragDropEffects.Move Else e.Effect = DragDropEffects.None End If End Sub Private Sub lableEventHandler(ByVal sender As Object, ByVal eMap As System.Windows.Forms.MouseEventArgs) lbl = CType(sender, Label) 'Begin drag operation,data to be dragged is the lbl lbl.DoDragDrop(lbl, DragDropEffects.Move) End Sub
Again, you need to pass the Panel to the first argument of DoDragDrop. You're passing the Label.
so i have remained with this below and the form's DragDrop and DragEnter Events, but when the mouse move is on the label, the panel moves far away to the right past the point of drop and past the screen area.
VB Code:
Private Sub Addlabel() lbl = New Label pnl.Controls.Add(lbl) AddHandler lbl.MouseDown, AddressOf lableEventHandler lbl.Location = New Point(24, 21) lbl.Size = New Size(111, 98) 'pnl.AllowDrop = True lbl.Text = Me.RichTextBox1.Text End Sub Private Sub lableEventHandler(ByVal sender As Object, ByVal eMap As System.Windows.Forms.MouseEventArgs) lbl = CType(sender, Label) 'Begin drag operation,data to be dragged is the lbl pnl.DoDragDrop(pnl, DragDropEffects.Move) End Sub
Its Okay. I got it. I needed to set the drag start point in that eventhandler for the label.
All i can say is thanks JMC. You will always be in the comments of my code. ;)
Make good use of the PointToClient and PointToScreen methods to convert coordinates from one controls coordinate system to amother.
Thanks JMC, and its time to give the project back to the forum.
Although it still has one more issue:
-->When You have one panel on the screen, every thing works fine and its ok.
But when you have more than one,say two(panel1 and panel2) and you move one panel
(say panel1) with the mouse over the label, it will move fine, but if the mouse is
shifted to Panel2 and at the point where the the label is on panel2, then a drag is
made, it will move panel1 to the point of drop instead of panel2.
Any Idea To Fix that will be highly appreciated.
I will look into PointToClient and PointToScreen and see how i can go about it.
JMC. Lets finish this. I have used PointScreen and it has helped me and now i can even be able to resize the panel but i have failed to solve the above problem.
Any Idea how i can solve it?
As I've said numerous times, whatever you pass to the first argument of DoDragDrop is what you get back from the e.Data property in the DragDrop event. If your code is moving the wrong Panel then it must be getting the wrong Panel from the e.Data property, which means that you must be passing the wrong Panel to DoDragDrop in the first place. Pass the correct Panel to the DoDragDrop method and you'll get the right Panel back at the end, thus you'll move the correct Panel. The Panels are parented by the form and the Labels are parented by the Panels. You can use a single MouseDown event handler for every Panel and every Label and use that general relationship like so:Now you've got a reference to the Panel that was either clicked itself, or contains the control that was clicked, so you simply pass 'ctl' to DoDragDrop and you'll get the correct Panel back when it coms time to actually move it.VB Code:
Dim ctl As Control = DirectCast(sender, Control) While ctl IsNot Me ctl = ctl.Parent End While
Still not coming.
This is what i have.
VB Code:
Private ctrl As Control Private Sub MyEventHandler(ByVal sender As Object, ByVal eMap As System.Windows.Forms.MouseEventArgs) Dim m_pt As New Point() 'cast object into a panel pnl = CType(sender, Panel) 'get the location point of the Panel(sender) we are copying 'get the point of click on the panel m_pt.X = pnl.PointToScreen(New Point(eMap.X, eMap.Y)).X m_pt.Y = pnl.PointToScreen(New Point(eMap.X, eMap.Y)).Y - 20 If eMap.Button = System.Windows.Forms.MouseButtons.Right Then cmnuDrawPanel.Enabled = False cmnuRemovePanel.Enabled = True 'Locate/Show the context menu, just below that label point Me.ContextMenuStrip1.Show(Me, m_pt) End If 'get the start point of the label we are tryinng to drag, then start dragging the label Me.dragStartPoint = pnl.PointToScreen(New Point(eMap.X, eMap.Y)) 'You Only Want To Drag The Panel If The User Clicks The Left Mouse Button If eMap.Button = Windows.Forms.MouseButtons.Left Then 'Begin drag operation,sets the drag object to be the pnl ctrl.DoDragDrop(pnl, DragDropEffects.Move) End If End Sub Private Sub lableEventHandler(ByVal lblSender As Object, ByVal eMap2 As System.Windows.Forms.MouseEventArgs) lbl = CType(lblSender, Label) Dim lbl_pt As New Point 'get that point on the label lbl_pt.X = New Point(eMap2.X, eMap2.Y).X + 25 lbl_pt.Y = New Point(eMap2.X, eMap2.Y).Y + 20 If eMap2.Button = System.Windows.Forms.MouseButtons.Right Then cmnuDrawPanel.Enabled = False cmnuRemovePanel.Enabled = True 'Locate/Show the context menu, just below that label point Me.ContextMenuStrip1.Show(pnl, lbl_pt) End If Me.dragStartPoint = pnl.PointToScreen(New Point(eMap2.X, eMap2.Y)) 'You Only Want To Drag The Panel If The User Clicks The Left Mouse Button If eMap2.Button = Windows.Forms.MouseButtons.Left Then 'Begin drag operation,sets the drag object to be the pnl ctrl.DoDragDrop(pnl, DragDropEffects.Move) End If End Sub Private Sub pnl_Lbl_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles pnl.MouseDown, lbl.MouseDown ctrl = DirectCast(sender, Control) While ctrl IsNot Me ctrl = ctrl.Parent End While End Sub
Oops, I left out a little bit in that last code example that you should have picked up on. Also, you're making that more complex than is necessary. The following is not a complete solution as it omits the middle parts of the drag and drop operation, thus I haven't tested it but it is a simple way to start and end the operation. It may need some tweaking because, as I said, I haven't actually tested it.VB Code:
Public Class Form1 Private Structure DragData ''' <summary> ''' The control being dragged. ''' </summary> Public DraggedControl As Control ''' <summary> ''' The point from which the control was dragged in screen coordinates. ''' </summary> Public DragOrigin As Point End Structure 'This method should handle the MouseDown event for every Panel and every Label. Private Sub DragableControl_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) 'Get a reference to the control that the mouse button was depressed over. Dim ctl As Control = DirectCast(sender, Control) 'Get a reference to the Panel that the mouse button was depressed over. While ctl.Parent IsNot Me ctl = ctl.Parent End While Dim data As DragData data.DraggedControl = ctl data.DragOrigin = Windows.Forms.Cursor.Position ctl.DoDragDrop(data, DragDropEffects.Move) End Sub 'This method should handle the DragDrop event for every control that can be dropped on, which basically means everything. Private Sub DropTarget_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Dim data As DragData = DirectCast(e.Data.GetData(GetType(DragData)), DragData) Dim draggedControl As Control = data.DraggedControl Dim dragOrigin As Point = data.DragOrigin Dim currentMouseLocation As Point = Windows.Forms.Cursor.Position 'Calculate the distance in each direction the control has been dragged. Dim deltaX As Integer = currentMouseLocation.X - dragOrigin.X Dim deltaY As Integer = currentMouseLocation.Y - dragOrigin.Y 'Move the control that distance. Dim newLocation As Point = New Point(draggedControl.Left + deltaX, draggedControl.Top + deltaY) draggedControl.Location = newLocation End Sub End Class
Phew....Urrgh!!! I have tried it and its like breaking the house 3/4 way to rebuild it again!.
JMC,Thanks for your response but i cant get to do the above in the attached project! i am getting everything screwed up....and getting more confused. i know this is simpler than how it seems to be complex.
If you would spend some time, Please look through the attached project and see how i can fit this in and repost it. I will be more than glad.
JMC, according to what you have told me to do, this is what i have....With a single MouseDown event handler for every Panel and every Label.
Check out my new features while dragging and resizing too. ;)
JMC, I followed up your method and it works. Ive posted the newUpdate in the above Post. Except that it disorganises my custom movecursor and my resizer.
For The Custom Cursor:
When More Than One Panel Is On The Form And I shift the Mouse from one Panel To Another for a mouse drag. My SizeAll Cursor Does Not Show Immediately Not Until Click To Drag The Panel Again
For The Resizer:
If i have more than one Panel,the Reiser doesnt See Which Panel Is it Belongs To Even When You Click On The Panel.It only works the newly added panel.
***EDIT***
Toview the resizer, click on the panel. But this will only happen when you click on the newly added panel on the form.
Got It. Just needed to leave "ctrl" as a class variable, i had redefined it somewhere else. But the Resizer problem is still on.
JMC,back again.
On the form that i create/draw the panels. I have labels on it pre-added from another form. I can be able to draw my "Stationery ToolTip" only when the mouse is not pointed on the a label there. How can i get it to show up even when the mouse is pointed on the label.
The main point here is that i want to use the text in the label to be the criteria for the information to show on the tooltip. If the pointer is pointed just on the mere part of the form, no information should show up in the Panel.
I thought it would take the same scenario of the labels added on the panel and i just call the event handler...but alas. No Luck.
***EDITS***
Another thing is that when i move my panel and it moves over the label on the form, the Panel and the triangle region always fall below the label, so the label is always on top if the panel or trangle sa-passes through it.
I tried to use SendToBack and BringTofront when adding both the panel and the labels and am i had ZERO luck! Any Idea how i can do away with this?