Search code examples
vb.netvisual-studiouser-interfaceresponseuserform

Improve UI responsiveness on windows form application


I am currently working on a project and decided to create a user interface for it using visual studio with a windows forms application(Visual Basic).

The problem I'm facing is that the user interface doesn't respond as quickly and smoothly as I'd like it to. Mainly, I am using pictures as buttons to make the user form look more modern. However, when I hover my mouse over a "button" it takes a while until the "highlighted button" appears.

P1 is the picture of the "normal button" and P2 is the picture of the "highlighted button".

Here is the short code I have for now:

Public Class Main

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load


End Sub

Private Sub PictureBox1_MouseHover(sender As Object, e As EventArgs) Handles P1.MouseHover
    P1.Visible = False
    P2.Visible = True
End Sub

Private Sub P2_MouseClick(sender As Object, e As MouseEventArgs) Handles P2.MouseClick
    'Call cmdInit()
    'Call cmdConnectRobot()
    'Call cmdUnlock()
End Sub

Private Sub Main_MouseHover(sender As Object, e As EventArgs) Handles Me.MouseHover
    If P2.Visible = True Then
        P2.Visible = False
        P1.Visible = True
    End If
End Sub

Private Sub P4_Click(sender As Object, e As EventArgs) Handles P4.Click

End Sub
End Class

Another problem I'm facing is that when I call other subs, the user form becomes unresponsive while the sub is running. I researched and found that I could implement multi threading or async tasks but I'm a bit lost and would be extremely grateful if someone could guide me or point me in the right direction.

Thanks in advance!!


Solution

  • In this case your UI is responsive, however the MouseHover event is only raised once the mouse cursor has hovered over the control for a certain amount of time (default is 400 ms), which is what is causing the delay.

    What you are looking for is the MouseEnter event, which is raised as soon as the cursor enters ("touches") the control:

    Private Sub P1_MouseEnter(sender As Object, e As EventArgs) Handles P1.MouseEnter
        P1.Visible = False
        P2.Visible = True
    End Sub
    

    You can then use that together with the MouseLeave event on the second picture box to switch back to the non-highlighted image:

    Private Sub P2_MouseLeave(sender As Object, e As EventArgs) Handles P2.MouseLeave
        P1.Visible = True
        P2.Visible = False
    End Sub
    

    However switching picture boxes like this is not optimal. I recommend you to look into how you can use Application Resources, then modify your code to only switch the image that one picture box displays.

    Here are the basic steps:

    1. Right-click your project in the Solution Explorer and press Properties.

    2. Select the Resources tab.

    3. To add an image either:

      a. Drag and drop the image onto the resource pane.

      b. Click the arrow next to the Add Resource... button and press Add Existing File....

    Now, in your code add this right below Public Class Form1:

    Dim ButtonNormal As Image = My.Resources.<first image name>
    Dim ButtonHighlighted As Image = My.Resources.<second image name>
    

    Replace <first image name> and <second image name> with the names of your button images.

    Now you only need one picture box for the button:

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        P1.Image = ButtonNormal
    End Sub
    
    Private Sub P1_MouseEnter(sender As System.Object, e As System.EventArgs) Handles P1.MouseEnter
        P1.Image = ButtonHighlighted
    End Sub
    
    Private Sub P1_MouseLeave(sender As System.Object, e As System.EventArgs) Handles P1.MouseLeave
        P1.Image = ButtonNormal
    End Sub