Home » VB.NetRSS

How to move the lineshape control at runtime freeely with mouse pointer

Hi 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 also 

2) 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 .


 

14 Answers Found

 

Answer 1

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 Sub
If 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.
 

Answer 2

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 Sub
Regards,
 

Answer 3

Hello 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
 

Answer 4

OK, 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  also 
If 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  
 

Answer 5

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 Point

    Dim dragStartPoint As Boolean = False
    Dim dragEndPoint As Boolean = False

    Private 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.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
        End If
    End Sub

    Private 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 Sub

    Private Sub ShapeContainer1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ShapeContainer1.MouseUp
        dragStartPoint = False
        dragEndPoint = False
    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 Class

Hope this help.

 

Answer 6

Hi 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
 

Answer 7

Hi 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.
 
 

Answer 9

Great work John, i'm really impressed by your work.

 

Answer 10

Thank you Jeff, I am glad I can be helpful and let me know if you have any ideas that we can blog about.
 

Answer 11

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
 

Answer 12

Hi 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
 

Answer 13

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 Class

And 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 Class

Greetings,

   Mike

 

Answer 14

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 Point

    Dim dragStartPoint As Boolean = False
    Dim dragEndPoint As Boolean = False

    Private 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.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
        End If
    End Sub

    Private 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 Sub

    Private Sub ShapeContainer1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ShapeContainer1.MouseUp
        dragStartPoint = False
        dragEndPoint = False
    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 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.

I just start to learn it, Now I have a more clear idea about it.
 
 
 

<< Previous      Next >>


Microsoft   |   Windows   |   Visual Studio   |   Follow us on Twitter