MouseLeave Event Doesn't Trigger After a Click? - vb.net

I have a simple issue in my Windows Form. I have a listbox that is acting as a log for some serial data I have input, and would like to be able to use the scroll wheel to move thru it. In order to do this, I have a variable, hoverList, set to 0 initially, which becomes 1 inside the MouseEnter event for the listbox. Then for the MouseWheel event, I increase or decrease the selected index in the listbox, but only if hoverList is 1. I expect that when the mouse leaves the area above the listbox, the MouseLeave event will fire, which sets hoverList to 0 and stops allowing "scrolling". This works fine, until I click in the listbox; I can still scroll just fine, but now I can scroll the listbox everywhere on my screen. It seems that clicking inside the listbox doesn't allow the MouseLeave event to ever trigger. Is this the case? And if so, is there a workaround that avoids this problem? Code for the 3 events is shown below
Private Sub LstSerialData_MouseLeave(sender As Object, e As EventArgs) Handles lstSerialData.MouseLeave
hoverList = 0
End Sub
Private Sub LstSerialData_MouseEnter(sender As Object, e As EventArgs) Handles lstSerialData.MouseEnter
hoverList = 1
End Sub
Private Sub Form1_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseWheel
If hoverList Then
If e.Delta > 0 Then
If lstSerialData.SelectedIndex > 10 Then
lstSerialData.SelectedIndex -= 10
Else
lstSerialData.SelectedIndex = 0
End If
Else
If lstSerialData.SelectedIndex < lstSerialData.Items.Count - 10 Then
lstSerialData.SelectedIndex += 10
Else
lstSerialData.SelectedIndex = lstSerialData.Items.Count - 1
End If
End If
End If
End Sub

I have found the solution to the problem. When clicking in the listbox,it becomes the selected control; since it has a scrollbar, I am actually allowed to use the scroll wheel to scroll thru it. Moving the cursor off of the listbox disables my built in scroll, but doesn't deselect the listbox, meaning I can still scroll thru it. I edited my MouseEnter and MouseLeave events to select and deselect the listbox respectively. This means that as soon as my cursor leaves the listbox, regardless of whether or not I have clicked inside it, it is deselected and will no longer let me scroll thru it. It also means my ghetto workaround to allow scrolling was no longer needed.

Related

Use mouse scroll anywhere on screen in VB.net

I'm trying to setup global shortcut using mouse button and scrolling combination, (scrolling up (or down) whlie pressing right mouse button).
I'm thinking I should try to react to mouse scroll, but I have no idea how to detect mouse wheel outside of form.
Right now I got it to react to mouse click with timer and setting form to always on top (no prolem with it being always on top), but no idea how to progress with it.
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
If MouseButtons.HasFlag(MouseButtons.Right) = True Then
TextBox1.Text = "YES"
Else
TextBox1.Text = "NO"
End If
End Sub
Goal is to make it minimize aplications set by user with that shortcut, just in case that info is helpful. I have rest of the code just cant figure that part out.
EDIT:
It works inside form with this:
Private Sub ListBoxCHOWAJ_MouseWheel(sender As Object, e As MouseEventArgs) Handles ListBoxCHOWAJ.MouseWheel
If MouseButtons.HasFlag(MouseButtons.Right) = True Then
If e.Delta > 0 Then
TextBox1.Text = "up"
Else
TextBox1.Text = "down"
End If
End If
End Sub
You need a mouse hook to detect scrolling outside your application. Have a look at my InputHelper library and its low-level mouse hook.
To include it in your project, download the compiled DLL and add it as a reference:
Right-click your project in the Solution Explorer and press Add Reference...
Go to the Browse tab.
Locate the InputHelper DLL-file, select it and press OK.
You can do all your logic in the hook's MouseWheel event handler, no need for the timer any longer:
Imports InputHelperLib
Public Class Form1
Dim WithEvents MouseHook As New InputHelper.Hooks.MouseHook
Private Sub MouseHook_MouseWheel(sender As Object, e As InputHelperLib.InputHelper.Hooks.MouseHookEventArgs) Handles MouseHook.MouseWheel
If MouseButtons.HasFlag(MouseButtons.Right) = True Then
'Do something...
End If
End Sub
End Class
There's no need to check e.Delta like you did because it will never be 0.

Are ListviewItems ever truely deselected?

I have a listview with several items in it. If I have an item selected and click in an empty white space or anywhere else on the form the highlight is removed but .FocusedItem & .SelectedItems still report an item is selected.
I have events that I want to trigger when no listviewitems are selected, but that never seems to occur. How do I detect if no items are selected or does that ever actually happen after that first item gets clicked?
Private Sub lstCats_SelectedIndexChanged(sender As Object, e As EventArgs) Handles lstCats.SelectedIndexChanged
If IsNothing(lstCats.FocusedItem) Then
DisableGUI()
Else
EnableGUI()
DisplayQuestions()
End If
End Sub
Basically DisableGUI() will never execute.
Thanks!
You can deselect all items in the ListView by clicking on an empty part of the ListView control (that is not on one of the items). For example:
Private Sub lstCats_SelectedIndexChanged(sender As Object, e As EventArgs) Handles lstCats.SelectedIndexChanged
If lstCats.SelectedItems.Count = 0 Then
DisableGUI()
Else
EnableGUI()
DisplayQuestions()
End If
End Sub
Note if you click on an item in the ListView, SelectedItems will be > 0. If you click on the background of the ListView (not on an item), SelectedItems will be = 0. This assumes that there is part of the ListView control that does not contain an item.

How to create a fading form on focus lost &got event

I am doing project in vb.net
When i click on button open I opened form with no control box(minimize,maximize etc).set borderStyle to FixedToolWindow
I want to change the opacity of form on got focus & lost focus event.
I also used activated & deactivated event but doesnt working
Private Sub form_Deactivate(ByVal sender As Object, ByVal e As System.EventArgs)HandlesMyBase.Deactivate
Me.Opacity =0
End Sub
Private Sub form_Activated(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Activated
Me.Opacity = 1
End Sub
To do this you need to use a System.Windows.Forms.Timer. the implementation is very simple:
Have two variables called _fromOpactity and _toOpacity, and a constant OpacityStep = 0.05
on Form Activate or Deactivate set _fromOpacity and _toOpacity and start the timer to fade in/out.
In the timer Elapsed event handler, Increment or Decrement OpacityStep (depending on from/to) until the desired value is reached.
For a full example of how to do this, see this article.
Best regards,
Try 0.01 in your 2nd line. You used 0 and it will hide your form.
Because that when you click in form area , the form_Actived don't run.

Setting Focus on a Tab

I have a tab in a windows form called Wafer Map that has three sub-tabs. The First sub-tab is the called Map and has a Load and Skip button. I am trying to set the focus on the Wafer sub-tab on the Load button click. This is the following code I have tried to use.
Private Sub Load_Wafer_Layout_Map_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Load_Wafer_Layout_Map.Click
Wafer_Info.Enabled = True
Wafer_Info.Show()
End Sub
The Wafer_Info.Enabled = True is used to enabled all of the controls on the Wafer tab and works properly when the button is clicked. I have tried using .Focus() and .Show() to bring focus to the next tab but I am not have any luck getting to switch. Anyone have any suggestions?
Just set it:
tabControl.SelectedTab = yourTab
On the Tab Controls Tab Pages, just ensure you name the tab you are attempting to reference. Additionally, see MSDN TabControl.SelectedTab
The code that worked for me is Tab_WaferMap.SelectTab(1). Tab_WaferMap is my main tab and the 1 is the index of the sub tab I wanted to show
I came across this thread as i was looking for a solution to my own focus issue. I have a TabControl with many TabPages. Each TabPage is set to auto scroll due to overflowing content. The problem I ran into was the mouse scroll wheel would not function if the TabPage did not have focus. Since there is not an event for each tab click it made setting focus to each TabPage a challenge. It was not hard, but a challenge none the less. So, here is my code (assuming auto scroll true).
On form load sets focus to main TabPage:
Private Sub frmParent_Load(sender As Object, e As System.EventArgs) Handles Me.Load
TabControl1.TabPages(0).Focus()
End Sub
Sets focus to current TabPage by getting the index then setting focus.
This is triggered by TabControl1.SelectedIndexChange event.
Private Sub TabControl1_SelectedIndexChanged(sender As Object, e As System.EventArgs) Handles TabControl1.SelectedIndexChanged
Dim intTabIndex As Integer = TabControl1.SelectedIndex
TabControl1.TabPages(intTabIndex).Focus()
End Sub
I hope someone find this useful. It was very useful for me.
Joshua
You can also set the Selected Index of the tab (and sub-tab) using a (zero based) numeric value:
TabParent.SelectedIndex = 3
TabSub.SelectedIndex=2

Button not hiding when mouse leaves from bottom

I have a form where I want buttons at the very bottom edge of the form, with no gap to the border. These buttons shall be "auto-hide", so they only show when the mouse is in for example the lower 20 pixels of the form. So I use the MouseMove event to trigger this, like code below. However, if mouse leaves the form across the bottom edge, where the buttons are, then the buttons will obviously remain. But I want them to hide. So I need for this purpose to hide the buttons by some other event. Hence I try to hide them in the form's MouseLeave event. But this makes the buttons unclickable and in an erratic state, flashing on and off when the mouse goes over the button.. Why is this? And how can I avoid this problem to get such autohide feature?
Private Sub ZgScale_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseMove
If e.Y > Me.ClientSize.Height - 30 Then
Button1.Visible = True
Else
Button1.Visible = False
End If
End Sub
Private Sub ZgScale_MouseLeave(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.MouseLeave
Button1.Visible = False
End Sub
The MouseLeave event fires when the mouse is no longer directly on that control (or form).
If the mouse moves on to a child control, the event will fire.
You need to check whether the mouse is no longer on the form, like this:
If Not Me.ClientRectangle.Contains(Me.PointToClient(e.Location)) Then
Button1.Visible = False
End If
EDIT: Fixed
Windows has direct support built-in for this scenario. Also exposed in Windows Forms and WPF. Once you get the MouseMove event, set the Capture property on the control to True. That forces all mouse messages to be directed to the control, even if the mouse moves outside of the control window.
Once you see it moving outside of the control bounds, set Capture back to false and hide your control. Beware that capture is turned off when the user clicks the mouse so you'll probably have to turn it back on afterwards. Although it should be automatic, you'll get another MouseMove event. Could fail if the user moves the mouse really fast.