How to call an event? - vb.net

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.

Related

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.

event detection between different controls vb

I have a class A which contains 2 user controls declared as
Friend WithEvents CustInfo1 As WindowsApplication1.CustInfo
Friend WithEvents ServiceLocation1 As WindowsApplication1.ServiceLocation
Both have textBoxes. If value of textBoxA in custInfo1 changes then how can I make value of textBoxB in SeviceLocation1 also change
I will be most thankful if anyone can help me.
Thanks
You need to do the following:
Inside the CustInfo user control, you need to write code inside the textBoxA Changed event that raises an event from the CustInfo user control (e.g. TextBoxChanged event). RaiseEvent statement
Inside the ServiceLocation user control, create a public property getter and setter for whatever your textBoxB.Text is
On the form that contains both user controls, create code in the new CustInfo TextBoxChanged event and set the new property on the ServiceLocation1 user control.
All controls (also custom controls) have the property Controls, through which you can access the (sub) controls of that control. Now you can retrieve your textbox by calling the .Item(key) method on it. Then you can assign a event handler to it in your form or class.
Dim key As String = "textBoxA" 'Or simply the name of that TextBox in your CustInfo
Dim textboxA As TextBox = CustInfo1.Controls.Item(key)
AddHandler textBoxA.TextChanged, AddressOf mytextchangedhandler
Where that mytextchangedhandler handles the TextChanged event for that TextBox.
Personally I don't like this method too much, as you are relying on knowing either the name of the TextBox or the index in the Controls list of your usercontrol.
I would definitely go for the option to create your own event on your usercontrol. It is quite easy to do even! Below how to do it. In the code behind of your usercontrol, you'll have to add an event declaration:
Event MyTextBoxChanged(sender As Object, e As EventArgs)
Now we'll have to raise it, we do this by implementing the TextChanged event of the TextBoxA in your usercontrol (as you explained you wanted to do):
Private Sub TextBoxA_TextChanged(sender As System.Object, e As System.EventArgs) Handles TextBoxA.TextChanged
RaiseEvent MyTextBoxChanged(Me, EventArgs.Empty)
End Sub
Now we can simply implement this event (MyTextBoxChanged) in your Form as follows:
Private Sub CustInfo1_MyTextBoxChanged(sender As System.Object, e As System.EventArgs) Handles CustInfo1.MyTextBoxChanged
' Do something
End Sub
Obviously we still need to get the updated text, now we can create our own EventArgs that will give us the new (and/or old value) as you will want to have. We simply can inherit the System.EventArgs class and add some properties (for example a property OldText that holds the old text value and a property NewText that holds the new text value):
Public Class MyEventArgs
Inherits System.EventArgs
Private _OldText As String
Public ReadOnly Property OldText() As String
Get
Return _OldText
End Get
End Property
Private _NewText As String
Public ReadOnly Property NewText() As String
Get
Return _NewText
End Get
End Property
Public Sub New(oldText As String, newText As String)
_OldText = oldText
_NewText = newText
End Sub
End Class
Now we have to change the event definition and raising to use the MyEventArgs:
Event MyTextBoxChanged(sender As Object, e As MyEventArgs)
Private Sub TextBoxA_TextChanged(sender As System.Object, e As System.EventArgs) Handles TextBoxA.TextChanged
RaiseEvent MyTextBoxChanged(Me, New MyEventArgs(TextBoxA.Text))
End Sub
And also change the implementation in your Form:
Private Sub CustInfo1_MyTextBoxChanged(sender As System.Object, e As MyEventArgs) Handles CustInfo1.MyTextBoxChanged
MessageBox.Show(e.Text)
End Sub
More information about events can be found on our favorite spot MSDN.

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()

How to add event handler to local variable in VB.NET

I have a form in VB.NET that is used as a dialog in a mainform. Its instances are always locally defined, there's no field for it. When the user clicks the OK button in the dialog, it will fire an event with exactly one argument, an instance of one of my classes.
Since it is always a local variable, how can I add an event handler for that event? I've searched for myself and found something but I can't really figure it out...
Code for the event, a field in MyDialog:
public Event ObjectCreated(ByRef newMyObject as MyObject)
Code for the main form to call dialog : (never mind the syntax)
Dim dialog As New MyDialog()
dialog.ShowDialog(Me)
AddHandler ObjectCreated, (what do I put here?) //Or how do I add a handler?
As you can see I'm stuck on how to add a handler for my event. Can anyone help me? Preferrably with the best way to do it...
It's recommended, for consistency, that you use the same source and event args model as all system event handlers.
Create your own class inheriting from EventArgs, as:
Public Class MyObjectEventArgs
Inherits EventArgs
Public Property EventObject As MyObject
End Class
Then declare your event, and a handler method, like:
Public Event ObjectCreated As EventHandler(Of MyObjectEventArgs)
Private Sub Container_ObjectCreated(ByVal sender As Object, ByVal e As MyObjectEventArgs)
' Handler code here
End Sub
Then attach the handler to your event using:
AddHandler ObjectCreated, AddressOf Container_ObjectCreated
Additionally, you can use the Handles to attach to the event raised from your main form (assuming the name MainForm), as below:
Private Sub MainForm_ObjectCreated(ByVal sender As Object, ByVal e As MyObjectEventArgs) Handles MainForm.ObjectCreated
' Handler code here
End Sub
You need to write the subroutine that actually executes when the event is generated:
public Sub OnObjectCreated(ByRef newMyObject as MyObject)
...
End Sub
Then the handler is added:
AddHandler ObjectCreated, AddressOf OnObjectCreated
As a side note, ByRef does nothing here. All objects in VB are passed by reference. Only primitave variables (string, int, etc) by default use ByVal and can be set to ByRef

How to use the Show Event in 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.