Code to hide winform when application loses focus - vb.net

I have been trying to build a procedure that will hide my winform when the application loses focus. I was able to come up with some code, but is not working properly. Here is my code:
Public Sub New()
' This call is required by the designer.
InitializeComponent()
Me.LostFocus += New EventHandler(AddressOf Form1_LostFocus)
End Sub
Private Sub Form1_LostFocus(sender As Object, e As EventArgs)
Me.WindowState = FormWindowState.Minimized
End Sub
The error I am getting on line:
Me.LostFocus += New EventHandler(AddressOf Form1_LostFocus)
It says that Public Event is an event and cannot be called directly. Use RaiseEvent statement to raise an event.
I am not sure how to use RaiseEvent so i am looking for some help on this.

I don't think you need to add an event handler programmatically. Just put your code in the LostFocus event sub.
Just do this:
Private Sub Form1_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.LostFocus
Me.WindowState = FormWindowState.Minimized
End Sub

You are using C# syntax for your manual wiring.
For VB.Net, it should look like this:
AddHandler Me.LostFocus, AddressOf Form1_LostFocus
Or just add the Handles syntax to the method (as aphoria demonstrated):
Private Sub Form1_LostFocus(sender As Object, e As EventArgs) _
Handles Me.LostFocus
Me.WindowState = FormWindowState.Minimized
End Sub

Related

Working sample of Control.VisibleChanged Event in vb.net

I'm struggling to make the MSDN code sample for the Control.VisibleChanged event work: I don't see the MsgBox.
Private Sub Button_HideLabel(ByVal sender As Object, ByVal e As EventArgs)
myLabel.Visible = False
End Sub 'Button_HideLabel
Private Sub AddVisibleChangedEventHandler()
AddHandler myLabel.VisibleChanged, AddressOf Label_VisibleChanged
End Sub 'AddVisibleChangedEventHandler
Private Sub Label_VisibleChanged(ByVal sender As Object, ByVal e As EventArgs)
MessageBox.Show("Visible change event raised!!!")
End Sub 'Label_VisibleChanged
You need to "wire up" the events to the event handlers.
To start with, to get the code in HideLabel_Click to be called you need it to respond to a click on the button named "HideLabel".
There are two ways to do that: you can use AddHandler or the Handles clause.
To demonstrate the latter:
Option Strict On
Public Class Form1
Private Sub HideLabel_Click(sender As Object, e As EventArgs) Handles HideLabel.Click
myLabel.Visible = False
End Sub
Private Sub myLabel_VisibleChanged(sender As Object, e As EventArgs) Handles myLabel.VisibleChanged
MessageBox.Show("Visible change event raised!!!")
End Sub
End Class
However, you will notice that the message is shown even before the form appears. That is because of what goes on behind the scenes to create the form.
To avoid that happening, you can add the handler after the form has been shown:
Option Strict On
Public Class Form1
Private Sub HideLabel_Click(sender As Object, e As EventArgs) Handles HideLabel.Click
myLabel.Visible = False
End Sub
Private Sub myLabel_VisibleChanged(sender As Object, e As EventArgs)
MessageBox.Show("Visible change event raised!!!")
End Sub
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
AddHandler myLabel.VisibleChanged, AddressOf myLabel_VisibleChanged
End Sub
End Class
Another way, in VB2015 and later, is to use a "lambda expression" instead of a separate method, although then you cannot disassociate the handler from the event with RemoveHandler:
Option Strict On
Public Class Form1
Private Sub HideLabel_Click(sender As Object, e As EventArgs) Handles HideLabel.Click
myLabel.Visible = False
End Sub
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
AddHandler myLabel.VisibleChanged, Sub() MessageBox.Show("Visible change event raised!!!")
End Sub
End Class
Craig was kind enough to [and I quote verbatim] call attention to the importance of Option Strict when you add handlers manually using AddHandler. Without it, the "relaxed delegate convention" may allow adding handlers which don't exactly match the event signature that you won't be able to remove later.
Having said that, Option Strict On isn't a complete safeguard: notice how my last example compiles and works even with the wrong method signature for the handler.
[I suspect that the MSDN code sample was first created in C# as part of a larger example, so some parts have been lost in the translation and excerption.]
I get this is old but came across this post when looking for more information on VisibleChanged and couldn't help but notice that the accept answer may be misleading. If you are using a designer to create your Form and place objects on it, then the accepted answer will be fine. In fact you can get rid of the addHandler because the designer handles that for you. All you would need to do is use a handles clause with your label.
Private Sub Button_HideLabel(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
myLabel.Visible = False
End Sub 'Button_HideLabel
Private Sub Label_VisibleChanged(ByVal sender As Object, ByVal e As EventArgs) Handles myLabel.VisibleChanged
MessageBox.Show("Visible change event raised!!!")
End Sub 'Label_VisibleChanged
Where the issue lies with the accepted answer is if you arn't using a designer. Adding handle clauses to "wire up" simply won't work (we can make it work and if anyone is interested in that I'll be happy to post a code snippet of that, but it's not how the accepted answer lays it out). In your case all you need to do is call AddVisibleChangedEventHandler() to set up the handler. that's it. you could have done this by calling it in MyBase.Load
Private Sub Load_Form(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
AddVisibleChangedEventHandler()
End Sub
Private Sub Button_HideLabel(ByVal sender As Object, ByVal e As EventArgs)
myLabel.Visible = False
End Sub 'Button_HideLabel
Private Sub Label_VisibleChanged(ByVal sender As Object, ByVal e As EventArgs)
MessageBox.Show("Visible change event raised!!!")
End Sub 'Label_VisibleChanged
Private Sub AddVisibleChangedEventHandler()
AddHandler myLabel.VisibleChanged, AddressOf Label_VisibleChanged
End Sub
Once again I know this is dated but couldn't help but notice that (more or less assuming) that you are trying to get a msgBox to appear when you click a label. That is you click a label and then toggled the visibility of another label. The other label is the one where the event handler is on for visibility change. So that inevitably gets called when clicking the original label. IF you only want this msgBox to appear when clicking that label and not when the form loads as well, you should change the addHandler statement so that you are adding a handler on the click event.
Private Sub Load_Form(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
AddVisibleChangedEventHandler()
End Sub
Private Sub Label_VisibleChanged(ByVal sender As Object, ByVal e As EventArgs)
MessageBox.Show("Visible change event raised!!!")
End Sub 'Label_VisibleChanged
Private Sub AddVisibleChangedEventHandler()
AddHandler otherLabel.Click, AddressOf Label_VisibleChanged
End Sub 'AddVisibleChangedEventHandler
Also Option Strict On has nothing to do with addhandler (From my understanding, could be wrong. please enlighten me if that is the case). Option Strict On is only checking to see that you arn't implicitly typecasting. So for example:
Dim a As Double
Dim b As Integer
a = 10
b = a
results in an error when Option Strict is On but is totally legal if it is off. So in the case of you leaving off the handles clause, you'll never be implicitly typecasting and therefore is not needed.
Hope this helps anyone who sees this question

Marquee Progress Bar with Background Worker in VB.NET

I have a main form with a progressbar at the bottom status strip. It is set to marquee style. I want it to keep animating when
I run a long function. But when the function hits, the form and everything on it freezes, so II used a backgroundworker
to run the long function. But this gave me the following error inside the MyClass.BigFunction() code.
Cross-thread operation not valid: Control 'frmMainNew' accessed from a thread other than the thread it was created on.
"frmMainNew" is the main form on which the progressbar and backgroundworker are. I pass the form as a parameter to the MyClass object
when I initialize it.
This is the first time I am using backgroundworker, so what else do I need?
I have already looked at these examples and tried them, but nothing works. (1, 2, 3, 4, 5, 6).
I have to use this for other functions too.
My code:
Private WithEvents bgw As BackgroundWorker
Private Sub frmMainNew_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Try
Me.SuspendLayout()
'Other Functions
w_AddBackgroundWorkerForProgressBar()
Me.ResumeLayout()
Catch ex As Exception
Scube.Planner.ErrorHandler.DisplayError(ex)
End Try
End Sub
Private Sub w_AddBackgroundWorkerForProgressBar()
bgw = New BackgroundWorker
AddHandler bgw.DoWork, AddressOf bgw_DoWork
AddHandler bgw.RunWorkerCompleted, AddressOf bgw_Completed
'AddHandler bgw.ProgressChanged, AddressOf bgw_ProgressChanged
End Sub
Private Sub MyButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyButton.Click
Try
bgw.WorkerSupportsCancellation = True
bgw.RunWorkerAsync()
'MyClass.BigFunction() <--- Originally called from here
Catch ex As Exception
Scube.Planner.ErrorHandler.DisplayError(ex)
Finally
Me.Cursor = Cursors.Default
End Try
End Sub
Private Sub bgw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles bgw.DoWork
'Do your lenghty operations here
MyClass.BigFunction()
System.Threading.Thread.Sleep(10000)
End Sub
Private Sub bgw_Completed(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) Handles bgw.RunWorkerCompleted
If Not IsNothing(e.Error) Then
MessageBoxEx.Show(e.Error.ToString)
End If
ProgressBar1.Hide()
End Sub
Private Sub w_ShowProgressBar()
ProgressBar1.Show()
Me.Refresh()
System.Windows.Forms.Application.DoEvents()
End Sub
You cant and should not access your frmMainNew from your 'BigFunction()'. It is working on a separate thread and does not have access to the UI thread. We need to see what you are doing inside your bigfunction to tell you the problem. Im going to take a guess and say you are trying to update the progressbar values from within that function? If this is so then is the incorrect way to do so.
What you need to do is, set the progress in your BigFunction like so:
bgw.ReportProgress(Progress/Percentage)
and have an event for the progress changed and inside of that event is where you update the progress bar.
Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
Progressbar1.value = e.ProgressPercentage
End Sub

Changing button name if file exists?

I'm working on a custom GUI, my last step is for the button to change automatically check if the file exists or not on startup. The method below is my download/open button. Any help is appreciated!
Private Sub Button7_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button7.Click
If Dir("DownloadedFile.zip") <> "" Then
Process.Start("DownloadedFile.zip")
Else
WC.DownloadFileAsync(New Uri("http://download852.mediafire.com/3a688rz1a6ig/dk71cs34ihs3v6x/Devil+went+down+to+georgia.rar"), "DownloadedFile.zip")
MsgBox("Starting Download")
End If
End Sub
A subroutine is a seperate method that does not return a value. I would take the If statement out of your click eventhandler and put it in its own method as I stated like this.
Private Sub CheckForFile()
If Dir("DownloadedFile.zip") <> "" Then
Process.Start("DownloadedFile.zip")
Else
WC.DownloadFileAsync(New Uri("http://download852.mediafire.com/3a688rz1a6ig/dk71cs34ihs3v6x/Devil+went+down+to+georgia.rar"), "DownloadedFile.zip")
MsgBox("Starting Download")
End If
End Sub
Call it from your button like this.
Private Sub Button7_Click(sender As Object, e As EventArgs) Handles Button7.Click
CheckForFile()
End Sub
Then handle the Shown Event and call it from there. It will run as soon as the initial form is shown
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
CheckForFile()
End Sub
Responding to your comment You need to use the WebClient DownloadFileCompleted Event and the WebClient DownloadProgressChanged Event

.Net WindowsForms MouseDown event not firing

As a new user to VB, I am struggling to see why this code works in one project but not in another. This code works fine if I create a new project and 2 new forms but when I place in my project, it doesn't fire at all on either left or right click.
I have tried a try/catch statement, but no errors are being reported. How do I go about troubleshooting this to find out the error. I have tried to rem out code and run after each comment but still the same. I have even tried removing all other code on the form leaving just the 2 subs but no joy. Any help would be greatly appreciated.
frmMain
Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'TODO: This line of code loads data into the 'StorageDataSet1.Customers' table. You can move, or remove it, as needed.
Me.CustomersTableAdapter.Fill(Me.StorageDataSet1.Customers)
'TODO: This line of code loads data into the 'StorageDataSet.User' table. You can move, or remove it, as needed.
Me.UserTableAdapter.Fill(Me.StorageDataSet.User)
'Dim frmDepartmentsLive As New frmDepartment
'frmDepartmentsLive.Owner = Me
'frmDepartmentsLive.ShowDialog()
lblDate.Text = Now
Timer1.Start()
rdoCustomer.Enabled = False
rdoCustomer.Checked = True
rdoDepartment.Enabled = False
rdoDepartment.Checked = False
For Each ctrl In Me.Controls
If TypeOf ctrl Is Button Then
AddHandler CType(ctrl, Button).MouseDown, AddressOf btn_MouseDown
End If
Next
End Sub
Private Sub btn_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs)
If (e.Button = MouseButtons.Right) Then
Dim btn = CType(sender, Button)
frmRacks.buttonName = btn.Name.Replace("btn", "")
frmRacks.Show()
ElseIf (e.Button = MouseButtons.Left) Then
MessageBox.Show("To be coded")
End If
End Sub
frmRacks
Public Class frmRacks
Public buttonName As String
Private Sub racksfrm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
lblRacks.Text = buttonName
End Sub
Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click
Me.Close()
End Sub
End Class
Since the controls are on a panel, they are members of that panel's controls array, not the form's. This -- and other things -- are apparent if you look thru the form's designer (on solution explorer, click Show All, then open formXXX.designer.vb). DOnt change anything, but it shows how controls are created and added. So...
For Each ctrl In thepanelName.Controls
If TypeOf ctrl Is Button Then
AddHandler CType(ctrl, Button).MouseDown, AddressOf btn_MouseDown
End If
Next
If it is ONLY those buttons on the panel you can short cut it:
For Each btn As Button In thepanelName.Controls
AddHandler CType(ctrl, Button).MouseDown, AddressOf btn_MouseDown
Next

Is it possible to detect a Form mouseclick from a User Control

I have created a User Control and would like to be able to detect when the user clicks on the Form.
I have seen this question which is related but the suggestion to use the the Leave event doesn't always do what I want because the focus doesn't necessarily change when the user clicks the Form (my control could be the only control on the Form in which case focus stays with my control).
Any ideas?
I want to be able to do something like this from within the User Control:
Private Sub ParentForm_Click(sender As Object, e As System.EventArgs) _
Handles Me.Parent.Click
End Sub
I would do it slightly differently:
Private _form As Control
Private Sub UserControl_ParentChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.ParentChanged
If _form IsNot Nothing Then
RemoveHandler _form.Click, AddressOf ParentOnClick
End If
_form = Me.FindForm()
If _form IsNot Nothing Then
AddHandler _form.Click, AddressOf ParentOnClick
End If
End Sub
Private Sub ParentOnClick(ByVal sender As Object, ByVal e As EventArgs)
'...
End Sub
This gives it a little more resillience - if it is not a direct child of a Form, if its parent changes etc.
I figured out how to do this myself - for anyone interested I am doing the following:
Private _parentForm As Form
Private Sub UserControl_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
_parentForm = CType(Parent, Form)
AddHandler _parentForm.Click, AddressOf ParentForm_Click
End Sub
Private Sub ParentForm_Click(sender As Object, e As System.EventArgs)
debug.writeline("Parent form clicked")
End Sub