How to move the lineshape control at runtime freeely with mouse pointer
-
Friday, February 19, 2010 7:28 AMHi PowerPacks ,The problem is I am drawing a LineShape control from Microsoft PowerPacks controls .dll , I am also moving the line when MouseDown,MouseMove,MouseUp,
But i am not able to drag the line in the correct position like in VB.net 2005
MouseDown
fdragging =true
startx =0
starty =0
MouseMove
m_control.StartPoint = New Point((m_control.StartPoint.X + e.X) - startx, (m_control.StartPoint.Y + e.Y) - starty)
m_control.EndPoint = New Point((m_control.EndPoint.X + e.X - startx), (m_control.EndPoint.Y + e.Y - starty))
MouseUp
fdragging = false
1) the things are i am not able to handle the MouseUp event also2) the pointer is slipping from the line & not able move the line in the correct direction.I am not able to move th lineshape control freely like in the design environment .And i am gettting the traces on the panel while moving the LineShape Control which looks odd to the end user .
VS
All Replies
-
Tuesday, February 23, 2010 9:26 AM
Hi SilverPlate,
If you want to move lineshape, you can change both the StartPoint and EndPoint of the control. Hope this helps.
Private fdragging As Boolean = False Private startx As Integer = 0 Private starty As Integer = 0 Private startPointRec As Point Private endPointRec As Point Private Sub Form1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseDown fdragging = True startx = e.X starty = e.Y startPointRec = m_control.StartPoint endPointRec = m_control.EndPoint End Sub Private Sub Form1_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseMove Dim movex As Integer = 0 Dim movey As Integer = 0 If fdragging Then movex = e.X - startx movey = e.Y - starty m_control.StartPoint = New Point(startPointRec.X + movex, startPointRec.Y + movey) m_control.EndPoint = New Point(endPointRec.X + movex, endPointRec.Y + movey) End If End Sub Private Sub Form1_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseUp fdragging = False End SubIf i misunderstand you, please let me know.
Regards
Jeff Shan
Please remember to mark the replies as answers if they help and unmark them if they provide no help.- Marked As Answer by Jeff Shan Friday, February 26, 2010 2:00 AM
- Unmarked As Answer by SilverPlate Friday, February 26, 2010 10:31 AM
-
Friday, February 26, 2010 10:26 AM
Hi Jeff Shan ,Thanks 4 replying ,its good but not for my requirement.My requirement is i have to drag n drop by mousedown on Lineshape control . Here is the code i used.Dim fdragging, fMousedown As Boolean Dim StartX, startY As Integer Private Sub LineShape1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles LineShape1.MouseDown fdragging = True StartX = e.X startY = e.Y End Sub Private Sub LineShape1_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles LineShape1.MouseMove Cursor.Current = Cursors.SizeAll If fdragging Then LineShape1.StartPoint = New Point(LineShape1.StartPoint.X + e.X - StartX, LineShape1.StartPoint.Y + e.Y - startY) LineShape1.EndPoint = New Point(LineShape1.EndPoint.X + e.X - StartX, LineShape1.EndPoint.Y + e.Y - startY) End If End Sub Private Sub LineShape1_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ShapeContainer1.MouseUp fdragging = False StartX = 0 startY = 0 End SubRegards,
VS -
Sunday, February 28, 2010 8:56 PMModeratorHello SilverPlate,
You probably do not want to handle events on the LineShape as it has limited region. Probably Jeff's version is good and you may want to hit test on mouse down to see if the line is selected.
John
John Chen -- See my team blog: http://blogs.msdn.com/vsdata. All my posts are provided "AS IS" with no warranties, and confer no rights. -
Monday, March 01, 2010 3:53 AMModeratorOK, it looks like this is a question follows up this thread:
http://social.msdn.microsoft.com/Forums/en-US/vbpowerpacks/thread/5c29b36a-a74b-4477-903c-90af7a43a8eb
Let's try to understand better your issue:
RE: the things are i am not able to handle the MouseUp event alsoIf you are trying to use LineShape to handle the mouse up, you will stuck. You should use its parent container control to handle it.
RE: the pointer is slipping from the line & not able move the line in the correct direction.
If you use the LineShape to handle the mouse move event, etc. You will see the behavior like the cursor is "slipping".
So the solution is you have to give up using the Mouse event on LineShape. Use ShapeContainer or Form's Mouse events.
I will post a sample later tonight.
John
John Chen -- See my team blog: http://blogs.msdn.com/vsdata. All my posts are provided "AS IS" with no warranties, and confer no rights. -
Monday, March 01, 2010 4:07 AMModerator
This sample (in form1 you have a LineShape1) works fine to me.
Public Class Form1
Const HitTestDelta As Integer = 3' The mouse position when mouse down
Dim oldMouseX As Integer
Dim oldMouseY As Integer' The line position when mouse down.
Dim oldStartPoint As Point
Dim oldEndPoint As PointDim dragStartPoint As Boolean = False
Dim dragEndPoint As Boolean = FalsePrivate Sub ShapeContainer1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ShapeContainer1.MouseDown
If (LineShape1.HitTest(MousePosition.X, MousePosition.Y)) Then
oldMouseX = e.X
oldMouseY = e.Y
oldStartPoint = LineShape1.StartPoint
oldEndPoint = LineShape1.EndPointdragStartPoint = MouseIsNearBy(oldStartPoint)
dragEndPoint = MouseIsNearBy(oldEndPoint)
If (Not dragStartPoint AndAlso Not dragEndPoint) Then
'If not drag either end, then drag both.
dragStartPoint = True
dragEndPoint = True
End If
End If
End SubPrivate Sub ShapeContainer1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ShapeContainer1.MouseMove
If (dragStartPoint) Then
LineShape1.StartPoint = New Point(oldStartPoint.X + e.X - oldMouseX, oldStartPoint.Y + e.Y - oldMouseY)
End If
If (dragEndPoint) Then
LineShape1.EndPoint = New Point(oldEndPoint.X + e.X - oldMouseX, oldEndPoint.Y + e.Y - oldMouseY)
End If
End SubPrivate Sub ShapeContainer1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ShapeContainer1.MouseUp
dragStartPoint = False
dragEndPoint = False
End SubPrivate Function MouseIsNearBy(ByVal testPoint As Point) As Boolean
testPoint = Me.PointToScreen(testPoint)
Return Math.Abs(testPoint.X - MousePosition.X) <= HitTestDelta AndAlso Math.Abs(testPoint.Y - MousePosition.Y) <= HitTestDelta
End FunctionEnd Class
Hope this help.
John Chen -- See my team blog: http://blogs.msdn.com/vsdata. All my posts are provided "AS IS" with no warranties, and confer no rights.- Marked As Answer by SilverPlate Tuesday, March 02, 2010 7:14 AM
- Unmarked As Answer by SilverPlate Tuesday, March 02, 2010 10:04 AM
-
Tuesday, March 02, 2010 7:16 AMHi John ,
Thanks its working .This is the thing i need 4 drag n drop Thank u very much .
set Form1.BackColor = white
But i have one more problem with LineShape while resizing the endpoints or drag n drop
1) Just take the end point or start point then rotate in a circular fashion then trailing or some paint things left on the screen .
How can we smoothly drag n drop the line like in vs designer without any traces or ?
I m also having problem with controls also
http://cid-038dd0e1974d763e.skydrive.live.com/self.aspx/Images/Trailing%20Effect%203%20Controls%20Handlers%20Appearing.JPG
Regards
VS- Edited by SilverPlate Tuesday, March 02, 2010 10:10 AM Trailing of control
-
Wednesday, March 03, 2010 7:18 AMModeratorHi SilverPlate,
What is the issue of "Just take the end point or start point then rotate in a circular fashion then trailing or some paint things left on the screen"? Could you please paste a picture as well.
I do know an issue when the line width is large enough and the drag will have some tailing. If you have the picture, I can confirm that.
For the controls, I think we need a separate thread to start with. We will need to see how you do the drag and drop on controls.
John
John Chen -- See my team blog: http://blogs.msdn.com/vsdata. All my posts are provided "AS IS" with no warranties, and confer no rights.- Edited by John Chen MsftModerator Wednesday, March 03, 2010 8:13 AM
-
Wednesday, March 03, 2010 8:11 AMModerator
Hi All,
Just post a blog based on this topic:
http://blogs.msdn.com/vsdata/archive/2010/03/02/how-to-move-a-shape-control-with-mouse-events.aspx
Hope this is helpful.
John Chen -- See my team blog: http://blogs.msdn.com/vsdata. All my posts are provided "AS IS" with no warranties, and confer no rights.- Proposed As Answer by Jeff Shan Wednesday, March 03, 2010 8:44 AM
- Marked As Answer by John Chen MsftModerator Tuesday, March 23, 2010 3:22 PM
-
Wednesday, March 03, 2010 8:44 AMGreat work John, i'm really impressed by your work.
Please remember to mark the replies as answers if they help and unmark them if they provide no help. -
Wednesday, March 03, 2010 4:59 PMModeratorThank you Jeff, I am glad I can be helpful and let me know if you have any ideas that we can blog about.
John Chen -- See my team blog: http://blogs.msdn.com/vsdata. All my posts are provided "AS IS" with no warranties, and confer no rights. -
Thursday, March 04, 2010 7:28 AM
Hi John ,
Thank you for the solution . i set in my appl according to my requirement.
I am not able upload the image bcoz sites are blocked . So i can reproduce by using some points
X1= 125
Y1 = 111
X2= 371
Y2 = 64
1) Hold X2,Y2 then move towards or reaching to x1,y1 by decreasing the distance b/w two points then paint marks or trailing are distributed across the form .
2) X1= 125 ,X2=128 ,y1=126 ,y2=126 rotate in a fashion that x1,y1 has to come down by increasing the distance b.w the 2 points then also paint marks or trailing are shown
3) X1=695 ,X2 =158,Y1=49,Y2=46
sample Form1
Hold the lineshape ctrl at left ,right ,center or at any place then drag to down to form's bottom position then u see the trailing of paint marks or lIneshape control ... This is what i am telling . How to get rid off this one .
Regards,
VS- Edited by SilverPlate Thursday, March 04, 2010 9:13 AM Trailing
-
Sunday, March 07, 2010 7:35 AMModeratorHi SilverPlate,
Could you please post a picture to any site that I can see or send it to me through johnchenms@live.com, where I only used to receive files.
I had a hard time to uderstand your issue without a picture.
Thanks!
John
John Chen -- See my team blog: http://blogs.msdn.com/vsdata. All my posts are provided "AS IS" with no warranties, and confer no rights. -
Friday, April 23, 2010 6:55 PM
Hi John,
thank you very much for your work. After days of working and searching I was so glad to find your solution :-)
I have added some lines to your code. Now it is possible to generate new LineShapes on runtime, just clicking the button.
You can also open a ContextMenuStrip with right mouse click on a line shape. For setting of color and line width.
But I have three problems that I still can not solve.
1) When I drag a LineShape over the blue colored PictureBox it leaves traces on it. Also on the button.
2) Dragging one ShapeLine over the other erases it like with a rubber.
3) extending a LineShape over the whole screen, picking the endpoint and dragging it fast around leaves traces on the form.
I have added a refresh to the mouse up handler, but that is not really satisfying.
If you have some extensions or remarks I would like to hear them.
Here is the code for Form1 (add a Button):
Imports Microsoft.VisualBasic.PowerPacks Public Class Form1 Private PictureBox1 As New PictureBox Private mLineShapes() As LineShape = Nothing Private mShapeContainer() As ShapeContainer = Nothing Private WithEvents mLsCtm1 As New ContextMenuStrip Private WithEvents mLsItm1 As New ToolStripMenuItem Private WithEvents mLsItm2 As New ToolStripMenuItem ' declare the ContextMenuStrip control Private mLsRtbContextMenuStrip As New ContextMenuStrip Private Sub Form1_Load _ (ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' make some settings for ContextMenuStrip and its items mLsCtm1.Items.AddRange(New ToolStripItem() {mLsItm1, mLsItm2}) mLsCtm1.Name = "ContextMenuStrip1" mLsCtm1.Size = New Size(142, 56) mLsItm1.Name = "Item1ToolStripMenuItem" mLsItm1.Size = New System.Drawing.Size(141, 26) mLsItm1.Text = "Linienfarbe" mLsItm2.Name = "Item2ToolStripMenuItem" mLsItm2.Size = New System.Drawing.Size(141, 26) mLsItm2.Text = "Linienstärke" PictureBox1.Height = 300 PictureBox1.Width = 500 PictureBox1.Location = New Point(300, 100) PictureBox1.BackColor = Color.Blue Me.Controls.Add(PictureBox1) End Sub Private Sub mLsItm1_Click _ (ByVal sender As System.Object, ByVal e As System.EventArgs) Handles _ mLsItm1.Click Dim colorPicker As New ColorDialog() Try colorPicker.ShowHelp = True Dim ClickedShapeContainerName As String = mLsCtm1.SourceControl.Name Dim siI As Integer Dim siClickedShapeContainerId As Integer = -1 ' get ID of clicked ShapeContainer For siI = 0 To mShapeContainer.Length If mShapeContainer(siI).Name = ClickedShapeContainerName Then siClickedShapeContainerId = siI Exit For End If Next ' get connected LineShape with same ID colorPicker.Color = mLineShapes(siClickedShapeContainerId).BorderColor If (colorPicker.ShowDialog() = Windows.Forms.DialogResult.OK) Then mLineShapes(siClickedShapeContainerId).BorderColor = colorPicker.Color End If Catch ex As Exception MessageBox.Show("Sub ITM1_Click: " & ex.Message, Me.Text) End Try colorPicker.Dispose() End Sub Private Sub mLsItm2_Click _ (ByVal sender As System.Object, ByVal e As System.EventArgs) Handles _ mLsItm2.Click Dim myDlgLineWidth As New DlgLineWidth Try Dim ClickedShapeContainerName As String = mLsCtm1.SourceControl.Name Dim siI As Integer Dim siClickedShapeContainerId As Integer = -1 ' get ID of clicked ShapeContainer For siI = 0 To mShapeContainer.Length If mShapeContainer(siI).Name = ClickedShapeContainerName Then siClickedShapeContainerId = siI Exit For End If Next ' get connected LineShape with same ID myDlgLineWidth.LineWidth = mLineShapes(siClickedShapeContainerId).BorderWidth If myDlgLineWidth.ShowDialog = Windows.Forms.DialogResult.OK Then mLineShapes(siClickedShapeContainerId).BorderWidth = myDlgLineWidth.LineWidth End If Catch ex As Exception MessageBox.Show("Sub ITM2_Click: " & ex.Message, Me.Text) End Try myDlgLineWidth.Dispose() End Sub Private Sub Button1_Click _ (ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles Button1.Click ' declare ShapeContainer counter Dim siSCCount As Integer If IsNothing(mLineShapes) Then siSCCount = 0 Else siSCCount = mLineShapes.Length End If ' create new ShapeContainer Dim sSCTemp As New ShapeContainer ' add ShapeContainer to Form sSCTemp.Parent = Me ' create new LineShape Dim sLSTemp As New LineShape sLSTemp.BorderColor = Color.Black sLSTemp.BorderWidth = 8 ' add LineShape to ShapeContainer sLSTemp.Parent = sSCTemp ' set starting and ending coordinates for the line sLSTemp.StartPoint = New System.Drawing.Point(siSCCount * 20, 60 + siSCCount * 60) sLSTemp.EndPoint = New System.Drawing.Point(100 + siSCCount * 20, 110 + siSCCount * 60) ' set new LineShape to top of z-order sLSTemp.BringToFront() sSCTemp.BringToFront() ' connect ContextMenuStrip to LineShape sLSTemp.ContextMenuStrip = mLsCtm1 ' add new LineShape to arrays ReDim Preserve mLineShapes(siSCCount) ReDim Preserve mShapeContainer(siSCCount) mLineShapes(siSCCount) = sLSTemp mLineShapes(siSCCount).Name = "LineShape" & siSCCount mShapeContainer(siSCCount) = sSCTemp mShapeContainer(siSCCount).Name = "ShapeContainer" & siSCCount ' add handlers AddHandler mShapeContainer(siSCCount).MouseDown, _ AddressOf ShapeContainerMouseDownEventHandler AddHandler mShapeContainer(siSCCount).MouseMove, _ AddressOf ShapeContainerMouseMoveEventHandler AddHandler mShapeContainer(siSCCount).MouseUp, _ AddressOf ShapeContainerMouseUpEventHandler End Sub Const HitTestDelta As Integer = 3 ' The mouse position when mouse down Dim oldMouseX As Integer Dim oldMouseY As Integer ' The line position when mouse down. Dim oldStartPoint As Point Dim oldEndPoint As Point Dim dragStartPoint As Boolean = False Dim dragEndPoint As Boolean = False Private Sub ShapeContainerMouseDownEventHandler _ (ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Dim siSCId As Integer Dim myShapeContainer As ShapeContainer myShapeContainer = CType(sender, ShapeContainer) Dim myLineShape As LineShape ' get index of the actual ShapeContainer in ShapeContainer array siSCId = Array.IndexOf(mShapeContainer, sender) If siSCId > -1 Then myLineShape = mLineShapes(siSCId) myShapeContainer.BringToFront() If (myLineShape.HitTest(MousePosition.X, MousePosition.Y)) Then oldMouseX = e.X oldMouseY = e.Y oldStartPoint = myLineShape.StartPoint oldEndPoint = myLineShape.EndPoint dragStartPoint = MouseIsNearBy(oldStartPoint) dragEndPoint = MouseIsNearBy(oldEndPoint) If (Not dragStartPoint AndAlso Not dragEndPoint) Then 'If not drag either end, then drag both. dragStartPoint = True dragEndPoint = True End If myLineShape.SelectionColor = Color.Transparent End If End If End Sub Private Sub ShapeContainerMouseMoveEventHandler _ (ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Dim siSCId As Integer Dim myShapeContainer As ShapeContainer myShapeContainer = CType(sender, ShapeContainer) Dim myLineShape As LineShape ' get index of the actual ShapeContainer in ShapeContainer array siSCId = Array.IndexOf(mShapeContainer, sender) If siSCId > -1 Then myLineShape = mLineShapes(siSCId) If (dragStartPoint) Then myLineShape.StartPoint = New Point(oldStartPoint.X + e.X - oldMouseX, oldStartPoint.Y + e.Y - oldMouseY) End If If (dragEndPoint) Then myLineShape.EndPoint = New Point(oldEndPoint.X + e.X - oldMouseX, oldEndPoint.Y + e.Y - oldMouseY) End If ' try something ... ' clean everything from trace marks 'myLineShape.Invalidate() 'myShapeContainer.Parent.Refresh() 'Me.Invalidate() 'For siI As Integer = 0 To Me.Controls.Count - 1 ' Me.Controls.Item(siI).Invalidate() 'Next End If End Sub Private Sub ShapeContainerMouseUpEventHandler _ (ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Dim siSCId As Integer Dim myShapeContainer As ShapeContainer myShapeContainer = CType(sender, ShapeContainer) Dim myLineShape As LineShape ' get index of the actual ShapeContainer in ShapeContainer array siSCId = Array.IndexOf(mShapeContainer, sender) If siSCId > -1 Then myLineShape = mLineShapes(siSCId) dragStartPoint = False dragEndPoint = False myLineShape.SelectionColor = Color.Transparent End If myShapeContainer.Parent.Refresh() ' try something ... 'Me.Invalidate() 'For siI As Integer = 0 To Me.Controls.Count - 1 ' Me.Controls.Item(siI).Invalidate() 'Next End Sub Private Function MouseIsNearBy(ByVal testPoint As Point) As Boolean testPoint = Me.PointToScreen(testPoint) Return Math.Abs(testPoint.X - MousePosition.X) <= HitTestDelta _ AndAlso Math.Abs(testPoint.Y - MousePosition.Y) <= HitTestDelta End Function End ClassAnd this is the code for sub dialog (add TextBox1 and Button1):
Public Class DlgLineWidth Private mLineWidth As Integer Public Property LineWidth() As Integer Get Return mLineWidth End Get Set(ByVal value As Integer) mLineWidth = value End Set End Property ' button "ok" Private Sub Button1_Click _ (ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles Button1.Click Try mLineWidth = CInt(TextBox1.Text) Catch ex As Exception MessageBox.Show("Please enter an integer." & ex.Message, Me.Text) End Try End Sub Private Sub DlgLineWidth_Load _ (ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles MyBase.Load TextBox1.Text = mLineWidth End Sub End ClassGreetings,
Mike

