How to use the Show Event in VB.net - vb.net

I try tu use this msdn snipped to execute some code right after my form loads:
Private Sub Form1_Shown(sender as Object, e as EventArgs) _
Handles Form1.Shown
Some Code
End Sub
But it seems that I am missing something. I get an errormessage that translated sounds like this:
The Handle requiere an WithEvents-Variable, which is defined in the contained type or its basis class... My Form is named Form1 so that should be ok. the error is marked in the second line of the code. Any ideas?

Instead of:
Handles Form1.Shown
do this:
Handles Me.Shown

Usually that is the sort of error you would get if you create the form in code and not in the designer. The designer will automatically declare the generated form as WithEvents. If you create the Form in code instead you have to declare it as WithEvents.
For example:
Public Form1 as frmMain
Would generate that error unless you add the handler yourself.
AddHandler Form1.Shown, AddressOf Form1_Shown
If you do this instead:
Public WithEvents Form1 as frmMain
wouldn't generate the error.
WithEvents is necessary on any object created if you want to use the handles clause in that way.

Related

Handles an Event from Control in another class

I want to fire an event in another class.
And my problem is I don't know how to make it.
I'm trying to use Inherits statement to my Form and add my class name to it, and it works as I hope:
Public Class Frm_Main_Copy
Inherits ToolStripMenuApp
'I have a ToolStripMenu that has declared before on my class and it sounds like this:
'Public Shared WithEvents Cat000x86_64App As ToolStripMenuItem
...
Private Sub IsClicked(ByVal sender As Object, ByVal e As EventArgs) Handles Cat000x86_64App.Click
End Sub
End Class
but the designer form messed up(returns a fatal error) and I should delete the Inherits statement, and the others.
Tried to act as form designer script(Trying to put this code to my class):
Friend WithEvents BlahBlah As RadioButton 'For example
It didn't worked,
Declaring a variable for my class and It didn't worked too
Searched on the Internet and it seems likely more complicated than I thought...
Anyone can help? Any help is appreciated.
A form is not a form unless it inherits, either directly or indirectly, the Form class. You cannot inherit any type that is not itself a form and expect your type to be a form. With that code, if ToolStripMenuApp is not a form then Frm_Main_Copy is not a form either, hence no form designer.
If what you're actually saying is that you have an instance of that ToolStripMenuApp that contains a TooStripMenuItem whose Click event you want to handle in Frm_Main_Copy then the first step is to not declare Cat000x86_64App as Shared. Frm_Main_Copy needs to declare a method capable of handling that event:
Private Sub IsClicked(ByVal sender As Object, ByVal e As EventArgs)
'...
End Sub
Note that there is no Handles clause because there's no WithEvents variable in that class whose event you are handling.
Next, Frm_Main_Copy must have access to the appropriate instance of ToolStripMenuApp. It's impossible for us to say how best to do that based on the information provided but it might be as simple as this:
Dim tsma As New ToolStripMenuApp
You then register your method as a handler for the appropriate event:
AddHandler tsma.Cat000x86_64App.Click, AddressOf IsClicked
If you use AddHandler, make sure to use RemoveHandler when you're done with either object. I suggest that you do some reading based on this information.

Create And Implement a Custom Form in VB.NET

I am trying to create a customized form class (CustomBorderlessForm) in VB.NET.
My Progress So Far
I created a new Class and named it CustomBorderlessForm.vb
I then proceeded to write the following code:
CustomBorderlessForm.vb
Public Class CustomBorderlessForm
Inherits Form
Dim _form As Form = Nothing
Public Sub New(form As Form)
_form = form
MsgBox("Testing: New()")
End Sub
Protected Overrides Sub OnMouseMove(e As MouseEventArgs)
MyBase.OnMouseMove(e)
MsgBox("Testing OnMouseMove()")
End Sub
End Class
Form1.vb
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim form As New CustomBorderlessForm(Me)
End Sub
End Class
Results of progress
A message box displays "Testing: New()" on load
Nothing shows on mouse move
As you can see, my problem lies with the events
Questions
Is it possible to create a form object and use that instead of the pre-populating form?
If so, can I give this form custom properties, such as, a border and some boolean values (shadow...etc), just like any other custom object/class?
What am I doing wrong in my current approach?
Why isn't the OnMouseMove being overridden?
Am I initialising the class wrong?
Can it even be done this way?
After creating a form you also need to show it. Change your logic to:
Dim form As New CustomBorderlessForm(Me)
form.Show()
Before you do that, I'd recommend changing from MsgBox to Console.WriteLine(), otherwise you can run into a fun/frustrating little cat and mouse game.
EDIT
Based on the comments, if, from VS you did a "Add New, Windows Form" you can just right-click the project, select property and on the Application tab change the Startup object to your new form. VS only allows you to do this with forms it creates for you (by default, more on this later).
If you wrote that file by hand (which is absolutely fine) you can perform the Show() like I did above and call Me.Hide() to hide the "parent" form. Unfortunately the Load event is fired before the Show event so if you place this in Form1_Load() it won't work. Instead you can use the Shown event like this:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim form As New CustomBorderlessForm(Me)
form.Show()
End Sub
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
Me.Hide()
End Sub
Another option has to do with "Application framework". You can read about it here however it basically handles application events that other languages have to manually implement. If you go into your project properties you can uncheck the "Enable application framework" checkbox. This will give you more option in the "Startup object" dropdown. If you add the following code to your project one of the items in the Startup object dropdown menu should now be "Loader"
Public Module Loader
<STAThread()>
Public Sub Main()
Dim form As New CustomBorderlessForm(Nothing)
form.ShowDialog()
End Sub
End Module
You'll notice that the above bypasses Form1 completely. Also, instead of Show() I'm using ShowDialog() because otherwise the form shows and then the program ends.

How to call an event?

How can I call a CharAdded event when my scintilla Text window has text added. I have tried adding this:
Private Sub Scintilla_CharAdded(ByVal sender As System.Object, ByVal e As ScintillaNet.CharAddedEventArgs) Handles Scintilla1.CharAdded
CType(TabControl1.SelectedTab.Controls.Item(0), Scintilla).AutoComplete.Show()
End Sub
But it only calls when the Scintilla window is implemented on my form in the design file. However I needed to work when I implement it like this:
Dim TextInput As New Scintilla
So is it possible to call this event when it is not placed directly in my designer?
Thanks.
If you want to use the Handles keyword, you can do so by defining your TextInput as a field of your form (a variable at the form-level, outside of any method). You then need to add the WithEvents modifier to the variable declaration, like this:
Public Class MyForm
Private WithEvents TextInput As New Scintilla
Private Sub Scintilla_CharAdded(sender As Object, e As ScintillaNet.CharAddedEventArgs) Handles TextInput.CharAdded
' ...
End Sub
End Class
If you can't define it as a field of your form, then you won't be able to use the Handles keyword. In that case, you'd need to resort to using the AddHandler and RemoveHandler commands to register your event handler with the object.

Handle an event of a control defined on another form

I have a form declared as s property WithEvents. If I add Handles formServers.FormClosing to a Sub declaration it works fine, but when I want to handle an event of a control within formServers I get the following error -
'Handles' in classes must specify a 'WithEvents' variable.
How do I correctly set this up? Thanks.
Private WithEvents formServers As New formServers
Private Sub txtServers_Closing(ByVal Sender As Object,
ByVal e As EventArgs) Handles formServers.txtServers.LostFocus
Me.SetServers()
If Me.ServersError Then
Dim Ex As New Exception("Error validating Servers.")
Dim ErrorForm = New formError(Ex, 101)
End If
End Sub
The error message is fairly misleading. The Handles keyword has several restrictions, it cannot work across different classes, it needs an object reference. You must use the more universal AddHandler keyword instead.
There are some additional problems in your scenario. Never use the LostFocus event, use Leave instead. And it is very important that you subscribe the event for the specific instance of the form, using As New gets you into trouble when you display the form multiple times, an ObjectDisposedException will be the outcome. Correct code looks like this:
Private formInstance As FormServers
Private Sub DisplayFormServer()
formInstance = new FormServers
AddHandler formInstance.txtServers.Leave, AddressOf txtServers_Closing
AddHandler formInstance.FormClosed, _
Sub()
formInstance = Nothing
End Sub
formInstance.Show()
End Sub
A much more elegant approach is to expose the event explicitly in your FormServers class. Make that look like this:
Public Class FormServers
Public Event ServersLeave As EventHandler
Private Sub txtServers_Leave(sender As Object, e As EventArgs) Handles txtServers.Leave
RaiseEvent ServersLeave(Me, EventArgs.Empty)
End Sub
End Class
The problem is that you do are not specifying WithEvents on the TextBox. Rather, you are specifying WithEvents on the Form. You can only use Handles on variables which you have declared directly with the WithEvents keyword. With the WithEvents being on the form, you will only be able to use Handles to handle events that are raised directly by the form itself. You will not be able to do so for events raised by any of its controls.
You can fix this in one of two ways. Either you can use AddHandler to register your event handler (rather than using the Handles keyword), or you can create a TextBox variable WithEvents and then set it to the appropriate TextBox object on the form, like this.
Private formInstance As New FormServers
Private WithEvents txtServers As TextBox
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
txtServers = formServers.txtServers
End Sub
Private Sub txtServers_LostFocus(Sender As Object, e As EventArgs) Handles txtServers.LostFocus
' ...
End Sub
The advantage of the latter approach, besides the more consistent, and possibly more elegant syntax, is that you don't have to remember to call RemoveHandler.

How does one override the OnShown Event of a form when creating a form programmatically?

I am trying to get a sound to play when a form is first shown (rather like a standard message box does for want of a better example). If using a standard form added through the designer I would generally do this by overriding the standard onshown event and then go on to call MyBase.OnShown(e)
The problem I've hit now is that the form is being created programmatically (Dim myForm as new Form etc) and as such I seem not to be able to use AddHandler to override this event. I don't doubt that I'm doing this in entirely the wrong way, but I'd appreciate any advice that can be offered. I would prefer advice from the perspective of VB.net, but I can just about muddle through in C#.
Form.OnShown is not an event. Rather, it is a method of the Form class which raises the form's Shown event. Here's the MSDN article that explains the OnShown method:
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.onshown.aspx
When you are making a derived class by using the form designer, you can override the OnShown method, but when you are simply accessing a form through its public interface, you need to use the Shown event instead. You can add an event handler for that event like this:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim f As Form1 = New Form1()
AddHandler f.Shown, AddressOf f_Shown
f.Show()
End Sub
Private Sub f_Shown(ByVal sender As Object, ByVal e As EventArgs)
End Sub
Since the form doesn't exist in code, you would actually have to call the event then.
Try writing out the showing code first:
Public Sub form_Showing(ByVal sender As Object, e As EventArgs)
// play sound
End Sub
then when you create your form, you add the handler of the event:
Dim f As New Form
AddHandler f.Shown, AddressOf form_Showing
f.Show()