How to add a specific event handler to a unspecified control? - vb.net

I'm looking to try and create something like the following:
If the user leaves the last textbox (for example let's say TextBox8), then a new textbox is created below textbox8 with the name textbox9. I have this part, but how would I make it so that if textbox9 is left, the same events happen, so on and so forth?
Private Sub TextBox8_LoseFocus(sender As Object, e As System.EventArgs) Handles TextBox8.LostFocus
' Textbox 9 creation code which then creates the next textbox etc.
End Sub
If anybody can offer a better way of doing this sort of thing

You can use AddHandler to add a eventhandler to a control you create at run time
AddHandler TextBox9.LostFocus, AddressOf TextBox8_LoseFocus

Related

How to write a single click event in Visual Basic?

I have created a form that allow users to close a form by clicking anywhere on the enlarged picture form (There are 3 objects to consider) and go back to the other form, which is called: "frmPhone". There's an actual picture on the form: "frmPhonePics" which is what I'm using to accomplish what I'm trying to do (was unable to insert an image on here. Sorry.) What I want to do is write a single click event to close the large picture form to allow the user to close it absolutely anywhere in the form, but I don't know how to do that. Here's the code I have so far:
Private Sub frmPhonePics_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Click
frmPhone.Show()
Me.Hide()
End Sub
It sounds as though you have a picture on your frmPhonePics form. If you double click that (from the VBA editor), you should be taken to the code - for example, you might see
Private Sub Image1_Click()
End Sub
Now all you have to do is add your code there:
Private Sub Image1_Click()
Me.Hide
frmPhone.Show()
End Sub
Note - the order matters, since frmPhone.Show() will "hijack" the code flow until it's dismissed, and in your code Me.Hide will not execute (so the form will not close) until frmPhone has been dismissed.
You can map the click handler for various object to one thing, if that is what you are asking:
Private Sub frmPhonePics_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles MyBase.Click, Handles picLarge.Click, Handles otherThing.Click
frmPhone.Show()
Me.Hide() ' should be Me.Close?
End Sub
Not sure why it is MyBase.Click in your code instead of Me.Click. Is this a subclassed form?
I'd strongly suggest using a DoubleClick instead of a single Click. The chances of an errant click doing the wrong thing is very great.
The easiest way is right from the designer. Write the sub routine, then for each control, in the properties window, click the events icon(thunderbolt) and assign the sub routine to the double-click event.
Alternatively, dispense with the Handles clause completely and use a series of Addhandler statements in the Load event handler. If you put a unique string in the names of the controls or if it's all the controls, you can iterate through the controls and use one addhandler statement for all of them
For Each c As Control In Me.Controls
AddHandler c.DoubleClick, AddressOf Ctrl_DoubleClick
Next
Private Sub Ctrl_DoubleClick(sender As Object, e As EventArgs)
'Do stuff
End Sub

Get to know which picturebox was clicked

In my current VBA project I have several pictureboxes which will activate a messagebox when you click on one of them. Is there any way for me to get to know which of the pictureboxes was clicked? I've added the code I have currently which doesnt allow me to pass any information to the sub so each picturebox will active the exact same message.
AddHandler newPictureBox.Click, AddressOf pic_Click
Public Sub pic_Click()
MsgBox("test")
End Sub
I see above you are using VB2010. Try this...
AddHandler newPictureBox.Click, AddressOf pic_Click
Private Sub pic_Click(sender As Object, e As EventArgs)
Dim thisPic As PictureBox = DirectCast(sender, PictureBox)
'thisPIC now is a reference to the box, you can use .Name, etc. to get it's properties.
End Sub
You could add a different handler to each picturebox, which would then delegate to another sub, passing along the info about which picturebox was clicked.
Why don't you use the picturebox.click event?
Just double click on your picturebox and it will automatically be using that event.
Then you can add your own code into the picturebox.click so they will have their own function.
If that's not what you want, please describe what it is that you're trying to do more clearly.

How to handle both selected index change of combobox column and keypress event of text box column in datagridviw editingcontrolshowing event?

I have a datagridview in winform, in which four columns exists.Out of which 1 comboxcolumn and other three textboxcolumn. I have handeled combobox selected index change properly and it working fine. I handle this on Datagridview_editigControlShowing() event. Now i want to handle other three textboxes keyprees event so user can only enter numeric value. Now i searched on net there are some solution, but when i add another handler in editingControlShowing() method at run time when i click on combobox, it shows error.But when i remove the addHandler for textbox its worked fine.
My Code is look like
Private Sub dgvPurchase_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles dgvPurchase.EditingControlShowing
Dim editComboBox As ComboBox = TryCast(e.Control, ComboBox)
If Not editComboBox Is Nothing Then
AddHandler editComboBox.SelectedIndexChanged, AddressOf editComboBox_SelectedIndexChanged
End If
'RemoveHandler dgvPurchase.EditingControlShowing, AddressOf dgvPurchase_EditingControlShowing
End Sub
Now is there any way to handle both of these if so please provide me the solution

Multiple event handlers for the same event in VB.NET

I've written two event handlers for the TextBox.Leave event for a TextBox1
The reason for this is that the first handler is a common one for multiple TextBox.Leave events which validates the values, and the second one is specific for the above TextBox1 which does some calculation of values.
My query is that can I know which of the two handlers will execute first when TextBox1.Leave happens?
(I know I can remove the code from the common handler to the specific one for TextBox1, but still I wish to know if there is a way.)
Thanks
As long as the event handlers are added using the AddHandler statement, the event handlers are guaranteed to be called in the same order that they were added. If, on the other hand, you are using the Handles modifier on the event handler methods, I don't think there is any way to be sure what the order will be.
Here's a simple example that demonstrates the order as determined by the order in which AddHandler is called:
Public Class FormVb1
Public Class Test
Public Event TestEvent()
Public Sub RaiseTest()
RaiseEvent TestEvent()
End Sub
End Class
Private _myTest As New Test()
Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
AddHandler _myTest.TestEvent, AddressOf Handler1
AddHandler _myTest.TestEvent, AddressOf Handler2
_myTest.RaiseTest()
RemoveHandler _myTest.TestEvent, AddressOf Handler1
RemoveHandler _myTest.TestEvent, AddressOf Handler2
End Sub
Private Sub Handler1()
MessageBox.Show("Called first")
End Sub
Private Sub Handler2()
MessageBox.Show("Called second")
End Sub
End Class
I'd recommend you change to having a single handler, and detect which textbox is being left:
Private Sub txt_Leave(sender As Object, e As System.EventArgs) Handles TextBox1.Leave, TextBox2.Leave
Dim txt As TextBox = DirectCast(sender, TextBox)
If txt Is TextBox1 Then
txt.Text = "Very important textbox!"
Else
txt.Text = "Boring textbox ho hum."
End If
End Sub
This is just additional information not related to the order of execution of multiple event handlers with the same "Handles" clause.
It may be of interest, though, to those wondering about when to use a "Handles" clause and when to use the "AddHandler" statement.
Addhandler is more useful when using a UDC (User Defined Control) to execute procedures/functions or manipulate data within a form.
UDCs know nothing about the form on which they have been attached or referenced.
They are generic and written for reuse in many projects.
Take (for example) the standard "TextBox" control.
Does TextBox know anything about the form on which it rests? No.
All its properties are available to the form but none of the form's properties is available to the Textbox.
(The Textbox is a pre-supplied "UDC", and Microsoft is the User defining it)
If you want your own UDC to operate on data in the main form, you define a public event within the UDC (let's call this event "UC_Update")
It is placed on a single line at the top of the code in the UDC:
Public Event UC_Update ' UC stands for "User Control"
When your UDC (let's call it "MyControl") wants to work with data on its parent form, it can call this event (within the UDC code) with the line:
RaiseEvent UC_Update
Within the code of the form on which this control has been placed or referenced, you attach this event belonging to your UDC to an instance of your control and "point" that event to another routine written in the form.
To do this, you use the "AddHandler" directive and an associated "AddressOf" operator.
Say the process you have written to manipulate data/controls in the form along with data/methods in your UDC, is called "MyControlUpdater".
It will be in your form and look like this:
Private Sub MyControlsUpdater()
......(code).......
end sub
The "(code)" may be lines that use data in your UDC (via public properties or public Subs/Functions) or use data or controls within your form. Your UDC can now do something with items on your form.``
You would place within your form's code the following:
AddHandler MyControl.UC_Update, AddressOf MyControlsUpdater
This directive is placed somewhere after the UDC has been instantiated:
Dim oMyControl as New MyControl
AddHandler oMyControl.UC_Update, AddressOf MyControlsUpdater
If, however, the UDC is physically on your form as "MyControl1", placed there via the Visual Studio Toolbox, then you would add the Handler in your form's "Load" procedure:
Private Sub Form1_Load(sender as object, e as eventargs) Handles Me.Load
AddHandler MyControl1.UC_Update, AddressOf MyControlsUpdater
It is important to note that you cannot pass parameters via this process (when using "AddressOf"). That is why there is no "sender" in the "MyControlsUpdater" subroutine. Values that relate to your UDC
must be obtained by way of public properties in that UDC. Public UDC functions and subroutines (subs) are also available.
If you are NOT working with a UDC (often the case) but with controls created by others such as Microsoft (and therefore the internal code of the control is not available), then you use the "Handles" clause to establish how the control is handled when a certain event arises (such as a "Click" on the control).
Private sub UpdateData(sender as object, e as eventargs) handles Textbox1.Click
........(code)......
End Sub
Of course, if your own UDC doesn't need to know anything about data on your form and you are referencing it rather than adding it physically to the form, you can just use the "Handles" delegation on your own UDC as per normal:
Dim MyControl1 as New MyControl
Private Sub UpdataData(sender as object, e as eventargs) _
handles MyControl1.Text.Leave
Here the form uses data in the control (via public properties) rather than the control using data within the form.

Rookie With Events; Causing Action after hitting F5

So yes I'm very new to creating my own custom events. I can do the basics when I put controls on a form but this one is a little more complex. I have an application that reads in a .TSV and populates a form with controls based on the number of objects it "reads." So for instance: I have a file that contains 10 people objects and my code populates a form with controls for each person. Easy stuff!
Now lets say I have a ComboBox with the items: "Alive", "Deceased", "Unborn". Right next to this I have a textbox for age. Now originally, this textbox is not enabled because the default value for the ComboBox is "Unborn". But lets say when the user selects "Alive", I want that textbox to become enabled so an age can be entered.
Obviously from me asking this and the title of this question, I don't know how to go about doing this. I don't really understand events and I learn by example but the MSDN examples don't quite cut it.
Any help (especially an awesome Step-by-Step guide) would be greatly appreciated.
From what I gather from the comments, you want to add events to a form object that is created at runtime. Use the AddHandler command to the object. Something to the effect of:
AddHandler NameOfFormObject.TypeOfAction, AddressOf HowToHandle
Private Sub HowToHandle(ByVal sender as System.Object, ByVal e As System.EventArgs)
DropDownMenu.enabled = True
End Sub
Doing it this way, you will be able to modify the events of an object created at runtime. In your case, it sounds like you'll want to use the action that Josaph recommended, and end up incorporating both solutions offered, like so
AddHandler ComboBox1.SelectedIndexChanged, AddressOf HowToHandle
Private Sub HowToHandle(ByVal sender as System.Object, ByVal e As System.EventArgs)
If DirectCast(sender, ComboBox).SelectedIndex = 0 'Alive
DirectCast(DirectCast(sender, ComboBox).Tag, TextBox).enabled = True
Else
DirectCast(DirectCast(sender, ComboBox).Tag, TextBox).enabled = False
End If
End Sub
You will want to use the ComboBox_SelectedIndexChanged() event to capture that the combo box item has been changed. At that point, you will need to check to see which combo box item has been selected and make a decision as to whether the TextBox should be enabled or not. Here is an example. Note: This example assumes that "Alive" is the first item in your combobox at the 0 index.
Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
If ComboBox1.SelectedIndex = 0 Then 'Alive
TextBox1.Enabled = True
Else
TextBox1.Enabled = False
End If
End Sub
Dynamically generate the combobox and add handler.
Dim cmb as New ComboBox
AddHandler cmb.SelectedIndexChanged, AddressOf ComboBox1_SelectedIndexChanged
Me.Controls.Add(cmb)
I suppose that as you will have 10 comboboxes... in the same way you'll have 10 textboxes.
In that case... once you attach and handle the event as AndyPerfect and Joseph... in that method you will need code something to know which of the Textboxs you need to enable/disable.
First you need to know which combobox triggered the event: this is done using the "sender" parameter. ctype(sender, Combobox) to access the methods and properties of the ComboBox.
Once you know which combo, you need to activate/deactivate the correct textbox.
To accomplish this, you'll need to add a reference to the TextBox in the "TAG" property of the Combobox at the moment of creating it.
Dim txt as new TextBox
Dim cmb as new ComboBox
cmb.Tag = txt
Then... you simple use:
ctype(ctype(sender, Combobox).Tag, TextBox).Enable = true
Here is how I ended up writing it in the end. I appreciate all the help! Thank you!
If DirectCast(sender, ComboBox).SelectedIndex = 2 Then
DirectCast(Me.Controls.Item(DirectCast(sender, ComboBox).Tag), TextBox).Enabled = True
Else
DirectCast(Me.Controls.Item(DirectCast(sender, ComboBox).Tag), TextBox).Enabled = False
End If