.NET TrackBar MouseDown follow cursor? - vb.net

I currently use this code to fix the bug where if you click somewhere on the Horizontal TrackBar it jumps to the middle then to the end of the TrackBar. So this code fixes that bug, which now jumps to the location you click.
But still a problem remains when I keep my mouse down and move it around the TrackBar the slider should follow but it just resets to beginning position, how do I make it follow right on top of cursor? would I need a timer control for that?
Private Sub tbTest_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles tbTest.MouseDown
Dim dblValue As Double
'Jump to the clicked location, bug FIX.
dblValue = (Convert.ToDouble(e.X) / Convert.ToDouble(tbTest.Width)) * (tbTest.Maximum - tbTest.Minimum)
tbTest.Value = Convert.ToInt32(dblValue)
End Sub

Make the method handle both the MouseDown() and MouseMove() events like this:
Private Sub tbTest_MovePointer(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles tbTest.MouseDown, tbTest.MouseMove
If e.Button = Windows.Forms.MouseButtons.Left Then
Dim dblValue As Double
'Jump to the clicked location, bug FIX.
dblValue = (Convert.ToDouble(e.X) / Convert.ToDouble(tbTest.Width)) * (tbTest.Maximum - tbTest.Minimum)
tbTest.Value = Convert.ToInt32(dblValue)
End If
End Sub
*Note the multiple events listed after the Handles keyword at the end of the first line. I also added a check to ensure the left mouse button is down.

Related

VB.NET TableLayout MouseEnter and leave event

I'm trying to do something that actually looks "simple" since several hours, but I cannot understand how to do it...and lurking over SO or different sites it seems that maybe is not that obvious.
The question is simple: i have a tableLayoutPanel with multiple rows, each one of them contains a panel, that contains several other controls.
I just want that when the mouse enters a row, the row background changes and when the mouse leave that row, it comes back to original color.
These are the simple event trappers, where pnlLayoutRow is the name of the panel containing the other controls:
Private Sub devRowMouseEnter(sender As System.Object, e As EventArgs) Handles pnlLayoutrow.MouseEnter
pnlLayoutrow.BackColor = Drawing.Color.FromArgb(&HFFFFEEAA)
End Sub
Private Sub devRowMouseLeave(sender As System.Object, e As EventArgs) Handles pnlLayoutrow.MouseLeave
pnlLayoutrow.BackColor = Drawing.Color.FromArgb(&HFFE7DEBD)
End Sub
The problem is: mouseEnter is correctly fired each time I enter the row, but Mouseleave is fired as soon as the mouse reach one of the controls inside the panel..that drives me crazy.
In other environment, I would solve this placing a transparent object all over the panel and trapping the mouseEnter and leave for that object..but it seems in VB trasparent objects do not exist.
Hope I have been clear in my explanation..it is pretty late in the night and I'm a bit tired.
thank you in advance
hope someone can help me
Cristiano
This version of your mouse leave event checks that the mouse is still within the bounds of your TableLayoutPanel and if it is then it exits without changing the color
Private Sub devRowMouseLeave(sender As System.Object, e As EventArgs) Handles pnlLayoutRow.MouseLeave
Dim p As Point = Me.PointToClient(MousePosition)
If p.Y > pnlLayoutRow.Top And p.Y < (pnlLayoutRow.Top + pnlLayoutRow.Height) And p.X > pnlLayoutRow.Left And p.X < (pnlLayoutRow.Left + pnlLayoutRow.Width) Then
Exit Sub
Else
pnlLayoutRow.BackColor = Drawing.Color.FromArgb(&HFFE7DEBD)
End If
End Sub
It seems to work ok for me,so I hope it is the same for you.
I've had a Google about mouse polling rates and by default, in windows, it's 125hz which might seem OK. However, if you move the mouse quickly, the mouse will enter and leave the panel more quickly that windows can detect it. Because of this, sometimes the .MouseEnter and .MouseLeave events don't fire. So I have here an alternative which will at least detect when the mouse leaves the panel. Add a Timer you your form called tmrPanelLeave
Private Sub devRowMouseEnter(sender As System.Object, e As EventArgs) Handles pnlLayoutRow.MouseEnter
pnlLayoutRow.BackColor = Drawing.Color.FromArgb(&HFFFFEEAA)
tmrPanelLeave.Start()
End Sub
Private Sub tmrPanelLeave_Tick(sender As Object, e As EventArgs) Handles tmrPanelLeave.Tick
Dim p As Point = Me.PointToClient(MousePosition)
If p.Y > pnlLayoutRow.Top And p.Y < (pnlLayoutRow.Top + pnlLayoutRow.Height) And p.X > pnlLayoutRow.Left And p.X < (pnlLayoutRow.Left + pnlLayoutRow.Width) Then
Exit Sub
Else
pnlLayoutRow.BackColor = Drawing.Color.FromArgb(&HFFE7DEBD)
tmrPanelLeave.Stop()
End If
End Sub

Mouse hovering event

I want to do an mouse hovering event, when the mouse is over an button I want to change button text color and font size, I have try this code but doesn't work:
Private Sub Command1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
Command1.ForeColor.MediumBlue()
Command1.FontSize = 10
End Sub
Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
Command1.ForeColor.White()
Command1.FontSize = 8
End Sub
Can anyone give me a suggestion i have search on Google and try different ways with mouse event handler but didn't work.
First, instead of tracking every mouse move, you can rely on MouseEnter and MouseLeave events of the button.
Second, do not forget to add Handles <Control>.<Event> clause at the declaration of your event-handling procedures.
Result:
Private Sub Command1_MouseEnter(sender As Object, e As EventArgs) _
Handles Command1.MouseEnter
Command1.FontSize = 10
End Sub
Private Sub Command1_MouseLeave(sender As Object, e As EventArgs) _
Handles Command1.MouseLeave
Command1.FontSize = 8
End Sub
Also please do not forget that some users are preferring keyboard control.
This means that
You might want to equip the button with an accelerator.
Command1.Text = "&Launch" (now Alt+L activates the button)
Note: accelerator character for winforms is &, for wpf is _.
You might want to make your entry/leave effect also when the button receives/looses keyboard focus (focus is moved using Tab and Shift+Tab key).
You can try making your changes into MouseEnter and MouseLeave
Private Sub RightButton_MouseEnter(sender As System.Object, e As System.EventArgs) Handles RightButton.MouseEnter
RightButton.ForeColor = Color.AliceBlue
RightButton.Font = New Font(RightButton.Font, 12)
End Sub
Private Sub RightButton_MouseLeave(sender As System.Object, e As System.EventArgs) Handles RightButton.MouseLeave
RightButton.ForeColor = Color.White
RightButton.Font = New Font(RightButton.Font, 10)
End Sub

How to change progress bar value by dragging mouse in vb.net

I am developing a media player and I'm trying to change value of Progress Bar using mouse cursor.
what i want is to set the value of progress bar where mouse cursor points after clicking + Dragging.
A progress bar is not the correct control to use for this. You should use a TrackBar instead.
But it can be made to work, with about -10 elegance points. The trickiest problem with ProgressBar is that it animates progress. That makes it slow to respond to your mouse moves. That animation can be disabled, but not perfectly. Closest you can get is:
Private Shared Sub ChangeProgress(bar As ProgressBar, e As MouseEventArgs)
If e.Button = Windows.Forms.MouseButtons.Left Then
Dim mousepos = Math.Min(Math.Max(e.X, 0), bar.ClientSize.Width)
Dim value = CInt(bar.Minimum + (bar.Maximum - bar.Minimum) * mousepos / bar.ClientSize.Width)
'' Disable animation, if possible
If value > bar.Value And value < bar.Maximum Then
bar.Value = value + 1
bar.Value = value
Else
bar.Value = value
End If
End If
End Sub
And call it from MouseDown and MouseMove event handlers:
Private Sub ProgressBar1_MouseMove(sender As Object, e As MouseEventArgs) Handles ProgressBar1.MouseMove
ChangeProgress(ProgressBar1, e)
End Sub
Private Sub ProgressBar1_MouseDown(sender As Object, e As MouseEventArgs) Handles ProgressBar1.MouseDown
ChangeProgress(ProgressBar1, e)
End Sub
It is workable, you'll notice that getting to 100% is a bit awkward. But, really, use a TrackBar instead. It was made to do this.

How to clear a textbox if i drag the text out

I have code to drag files into a textbox, but I would also like to have code to drag the file out of the textbox, thus clearing it.
Anybody have any ideas?
You can use the DoDragDrop method to do a drag & drop operation. It returns a DragDropEffects value that specifies if the data actually has been dropped somewhere in which case you can clear the text box.
Since a drag & drop operation shouldn't start before the mouse has been moved a bit while pressing the mouse button you need to check for that in the MouseDown and MouseMove events. SystemInformation.DragSize tells you how far the mouse should be moved before a drag & drop operation starts.
In the MouseDown event check if you actually want to start a drag (i.e left button is pressed and text box actually contains text). Then create a rectangle using the mouse location and the size given by SystemInformation.DragSize. In the MouseMove event check if the mouse is dragged outside the rectangle and call DoDragDrop:
Private _dragStart As Boolean
Private _dragBox As Rectangle
Private Sub srcTextBox_MouseDown(sender As Object, e As MouseEventArgs) Handles srcTextBox.MouseDown
' a drag starts if the left mouse button is pressed and the text box actually contains any text
_dragStart = e.Button = MouseButtons.Left And Not String.IsNullOrEmpty(srcTextBox.Text)
If _dragStart Then
Dim dragSize As Size = SystemInformation.DragSize
_dragBox = New Rectangle(New Point(e.X - (dragSize.Width \ 2),
e.Y - (dragSize.Height \ 2)), dragSize)
End If
End Sub
Private Sub srcTextBox_MouseUp(sender As Object, e As MouseEventArgs) Handles srcTextBox.MouseUp
_dragStart = False
End Sub
Private Sub srcTextBox_MouseMove(sender As Object, e As MouseEventArgs) Handles srcTextBox.MouseMove
If Not _dragStart Or
(e.Button And MouseButtons.Left) <> MouseButtons.Left Or
_dragBox.Contains(e.X, e.Y) Then Return
Dim data As New DataObject()
data.SetData(srcTextBox.Text)
' you can optionally add more formats required by valid drag destinations:
' data.SetData(DataFormats.UnicodeText, Encoding.Unicode.GetBytes(srcTextBox.Text))
' data.SetData("UTF-8", Encoding.UTF8.GetBytes(srcTextBox.Text))
' data.SetData("UTF-32", Encoding.UTF32.GetBytes(srcTextBox.Text))
Dim dropEffect As DragDropEffects = srcTextBox.DoDragDrop(data, DragDropEffects.Move)
If (dropEffect = DragDropEffects.Move) Then
srcTextBox.Text = ""
End If
_dragStart = False
_dragBox = Rectangle.Empty
End Sub
Private Sub destTextBox_DragOver(ByVal sender As Object, ByVal e As DragEventArgs) Handles destTextBox.DragOver
If e.Data.GetDataPresent(GetType(String)) Then
e.Effect = e.AllowedEffect And DragDropEffects.Move
Else
e.Effect = DragDropEffects.None
End If
End Sub
Private Sub destTextBox_DragDrop(ByVal sender As Object, ByVal e As DragEventArgs) Handles destTextBox.DragDrop
If e.Data.GetDataPresent(GetType(String)) Then
destTextBox.Text = e.Data.GetData(GetType(String)).ToString()
End If
End Sub
Dragging the mouse in a TextBox usually starts text selection. The above code changes this behavior. Users can't use the mouse any more to select text. This is obviously not a good idea since users wouldn't expect that. To allow both text selection with the mouse and dragging you need to control the selection mechanism. This means you need to create your own text box class.
I would suggest a different approach: Use a label that shows the value as the dragging source and/or destination. To allow editing you can create a hidden text box. If the user double clicks on the label you hide the label and show the text box. After the user finishes editing (by hitting enter or cancel) or if the text box looses focus you hide the text box and show the label again.
Check out the DragLeave Event on the TextBox
Easiest way will probably be to store it as a variable or in clip board if leaving app.
Private Sub TheTextBox_DragLeave(sender As System.Object, e As System.EventArgs) Handles TheTextBox.DragLeave
Clipboard.SetText(TheTextBox.Text)
TheTextBox.Clear() 'Optional
End Sub
Then you'll need to code what happens when you mouse up of course, or drag into or whatever. You could clear the textbox in one of these steps. Depends on your implementation.

Moving .NET controls at runtime

I am attempting to move all controls on a form down or up by the height of a menubar depending on whether it is visible or not. I have code which I think ought to work well for this, however it seems that Me.Controls is empty at runtime, so my for each loop is never entered. Could someone please offer a suggestion as to how I can move the controls?
Private Sub uxMenuStrip_VisibleChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles uxMenuStrip.VisibleChanged
For Each control As Control In Me.Controls
If control.Name <> "uxMenuStrip" Then
Dim temp As AnchorStyles = control.Anchor
control.Anchor = AnchorStyles.None
control.Top -= ((CInt(uxMenuStrip.Visible) * 2 - 1) * uxMenuStrip.Height)
control.Anchor = temp
End If
Next
Me.Height += ((CInt(uxMenuStrip.Visible) * 2 - 1) * uxMenuStrip.Height)
End Sub
Add a new Handler with Control and change location in address
Public Sub ChngPostion(ByVal sender As System.Object, ByVal e As System.EventArgs)
For Each cntrl As Control In Me.Controls
If cntrl.Name = sender.Name Then
cntrl.Location = New System.Drawing.Point(sender.Location.X,sender.Location.Y)
End If
Next
End Sub
As Michael Todd points out, Me.Controls can't be empty. Also, this might not work as well as you're thinking. Controls on WinForms apps are hierarchical. The only way to do this 100% cleanly is to make the move code recursive. IE, perform the same operation on every control in each control's controls collection. (Now I'm sounding like Dr. Seuss...) If your form is simple, this wouldn't be an issue, obviously.
At the end of the day, though, you'll probably be better off just putting everything on the form inside a Panel and just moving the Panel control explicitly by name. It would make what you're trying to do more clear.
Try this:
Private Sub uxMenuStrip_VisibleChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uxMenuStrip.VisibleChanged
Dim menu As Control = sender
Dim dh As Integer = IIf(menu.Visible, 1, -1) * menu.Height
For Each control As Control In Controls
If control.Parent Is Me And Not control Is menu Then
control.Top += dh
End If
Next
Height += dh
End Sub
Update:
Anyway, i strongly recomment using container, in case with MenuStrip - ToolStripContainer.