Adding an event handler when a subcontrol is instantiated - vb.net

I've got a custom FlowLayoutPanel: an "AlbumFlowLayout" which inherits from a FlowLayoutPanel and is used to hold a collection of UserControls ("AlbumItems"). Typically, this would reside on a form ("FrmMain")so that the hierarchy of items is:
Form ("FrmMain")
AlbumFlowLayout ("AlbumFlowLayout1")
AlbumItems (1 or more)
[Is there a way/what is the protocol] for adding a "WasClicked" handler to a created AlbumItem whenever it's created/added to the AlbumFlowLayout?
Ideally I'd like to encapsulate the handler construction code inside the AlbumFlowLayout so that it happens automatically whenever the code in FrmMain does an AlbumFlowLayout.Controls.Add of a new AlbumItem, rather than having a second line in the FrmMain add the handler before adding the control, e.g.:
Dim myItem As New AlbumItem
AddHandler myItem.WasClicked, AddressOf AlbumFlowLayout1.AlbumItem_WasClicked
AlbumFlowLayout1.Controls.Add(myItem)
Thanks!
-Pete

Plutonix had the solution. Here's what the final code looks like to use it:
Partial Public Class AlbumFlowLayout
Inherits FlowLayoutPanel
' A FlowLayoutPanel for handling collections of AlbumItems
Public SelectedItems As New List(Of String)
' Holds IDs of currently selected items
Private Sub AlbumFlowLayout_ControlAdded(sender As Object, e As ControlEventArgs) Handles Me.ControlAdded
' Wire up each user item as it's added so that it will pass its
' Wasclicked up to here
Dim myAlbumItem As AlbumItem = e.Control
AddHandler myAlbumItem.WasClicked, AddressOf Me.AlbumItem_WasClicked
End Sub
' Other methods...
' ...
Public Sub AlbumItem_WasClicked(ByVal sender As Object, e As EventArgs)
' Deselects all previously selected items. Doing this via a List to
' Allow for expansion item where we permit multi-selection via
' Control-key or the like; currently is single-select
Dim myItem As AlbumItem = sender
For Each itm As String In SelectedItems
If itm <> myItem.Name Then
DirectCast(Me.Controls(itm), AlbumItem).IsSelected = False
End If
Next
SelectedItems.Clear()
SelectedItems.Add(myItem.Name)
End Sub
End Class

Related

TabPage selection, move the Focus to the previous ActiveControl when a TabPage is reselected

I need some help to focus a particular control when a TabPage is revisited. I followed many other blogs, but I wasn't able to solve the problem myself.
I created the TabPages inside a MDIForm:
Public Sub Tab_Open(Of T As {Form, New})(name As String, NameofTab As String, Tabnumber As String)
Dim _formByName As New Dictionary(Of String, Form)
Dim Frm As Form = Nothing
If Not _formByName.TryGetValue(name, Frm) OrElse _formByName(name).IsDisposed Then
Frm = New T()
_formByName(name) = Frm
End If
Dim childTab As TabPage = New TabPage With {
.Name = NameofTab & " : " & Tabnumber,
.Text = NameofTab & " : " & Tabnumber,
.Tag = Frm.Name
}
Form1.tabForms.TabPages.Add(childTab)
Frm.TopLevel = False
Frm.FormBorderStyle = FormBorderStyle.None
Frm.Parent = Form1.tabForms.TabPages(Form1.tabForms.TabCount - 1)
Frm.Dock = DockStyle.Fill
Frm.Show()
Form1.tabForms.SelectedTab = childTab
Form1.tabForms.Visible = True
End Sub
Let's assume that in first TabPage the Focus was on a TextBox (with TabIndex = 4), now I may be click on the second TabPage.
After some calculations, when I select the previous TabPage, the Focus should be set to the TextBox with TabIndex = 4 again, but that's not happening.
I tried to create a Dictionary in the MDIForm as:
Public Tab_Last_Focus_info As New Dictionary(Of String, String())
and in SelectedIndexChanged I have this code:
Private Sub tabForms_SelectedIndexChanged(sender As Object, e As EventArgs) Handles tabForms.SelectedIndexChanged
If Tab_Last_Focus_info.ContainsKey(tabForms.SelectedTab.Name) Then
Dim FullTypeName1 As String = String.Format("{0}", Tab_Last_Focus_info.Item(tabForms.SelectedTab.Name))
Dim Indxval As String = String.Format("{1}", Tab_Last_Focus_info.Item(tabForms.SelectedTab.Name))
Dim FullTypeName As String = Application.ProductName & "." & FullTypeName1
Dim FormInstanceType As Type = Type.GetType(FullTypeName, True, True)
Dim frm As Form = CType(Activator.CreateInstance(FormInstanceType), Form)
Dim Focus_on As Integer = Integer.Parse(Indxval)
frm.Controls(Focus_on).Focus()
' Not working too =>
' frm.Controls(Focus_on).Select()
' Invisible or disabled control cannot be activated =>
' ActiveControl = frm.Controls(Focus_on) 'System.ArgumentException:
End If
End Sub
In the Form, which is opened via a Menu, I have this code for the Control that's focused:
Private Sub All_Got_Focus(sender As Object, e As EventArgs) Handles TB_ImageLoc.GotFocus, TB_CompWebsite.GotFocus,
TB_CompPinCD.GotFocus, TB_CompPAN.GotFocus, TB_CompName.GotFocus, TB_CompMobile.GotFocus,
TB_CompMD.GotFocus, TB_CompLL.GotFocus, TB_CompGSTIN.GotFocus, TB_CompFax.GotFocus, TB_CompEmail.GotFocus,
TB_CompCD.GotFocus, TB_CompAreaCity.GotFocus, RTB_CompADD.GotFocus, PB_Logo.GotFocus, DTP_CompEst.GotFocus, DGV_CompList.GotFocus,
CHKB_CompIsRegTrans.GotFocus, CB_CompStateID.GotFocus, CB_CompDistrictID.GotFocus, But_Upd.GotFocus, But_SelectLogo.GotFocus,
But_Search.GotFocus, But_Reset.GotFocus, But_Refresh.GotFocus, But_GridSelect.GotFocus, But_Exit.GotFocus, But_Edit.GotFocus,
But_Del.GotFocus, But_Add.GotFocus
If Form1.Tab_Last_Focus_info.ContainsKey(Form1.tabForms.SelectedTab.Name) Then
Form1.Tab_Last_Focus_info.Remove(Form1.tabForms.SelectedTab.Name)
End If
Form1.Tab_Last_Focus_info.Add(Form1.tabForms.SelectedTab.Name, New String() {Me.Name, Me.ActiveControl.TabIndex})
End Sub
Now in TabIndexChange I'm getting a correct value from the Dictionary, but I'm not able to focus on the required tab.
Kindly help and let me know what I am missing or what need to taken care for this issue or please let me know any other better idea for the same.
First thing, a suggestion: test this code in a clean Project, where you have a MDIParent and one Form with a TabControl with 2 o more TabPages, containing different types of Controls. Test the functionality, then apply to the Project that is meant to use it.
You need to keep track of the selected Control in a TabPage - the current ActiveControl - switch to other TabPages, restore the previous ActiveControl in a TabPage when it's brought to front again.
The procedure is simple, implemented as follows:
To keep track of the current ActiveControl - the Control that has the Focus, you need to know when a Control becomes the ActiveControl. This Control of course must be child of a TabPage.
The ContainerControl class (the class from which Form derives) has a protected virtual method, UpdateDefaultButton(), that's overridden in the Form class. It's used to determine which child Button is activated when a User presses the Enter Key.
This method is called each time a new Control becomes the ActiveControl: overriding it, we can be informed when this happens, so we can check whether the new ActiveControl is one we're interested in, because it's child of a TabPage of our TabControl.
When the new ActiveControl is one we need to keep track of, we can store the reference of this Control and the Index of the TabPage it belongs to in a collection, so we can then use this reference, when the selected TabBage changes, to set it again as the ActiveControl in its TabPage.
Here, to store the state, I'm using a Dictionary(Of Integer, Control), where the Key is the Index of the TabPage and the Value is the reference of its ActiveControl.
When the TabControl.Selected event is raised - after a TabPage has been selected - we can lookup the Dictionary and restore the previous ActiveControl of that TabPage if one was stored.
► Here, BeginInvoke() is used to defer the action of setting the new ActiveControl, because this also causes a call to UpdateDefaultButton() and this method is called before the TabControl.Selected event handler completes.
Public Class SomeMdiChildForm
Private tabPagesActiveControl As New Dictionary(Of Integer, Control)()
' This method is called each time a Control becomes the ActiveControl
Protected Overrides Sub UpdateDefaultButton()
MyBase.UpdateDefaultButton()
If TypeOf ActiveControl.Parent Is TabPage Then
Dim tabPageIdx = CType(CType(ActiveControl.Parent, TabPage).Parent, TabControl).SelectedIndex
If tabPagesActiveControl.Count > 0 AndAlso tabPagesActiveControl.ContainsKey(tabPageIdx) Then
tabPagesActiveControl(tabPageIdx) = ActiveControl
Else
tabPagesActiveControl.Add(tabPageIdx, ActiveControl)
End If
End If
End Sub
Private Sub TabControl1_Selected(sender As Object, e As TabControlEventArgs) Handles TabControl1.Selected
Dim ctrl As Control = Nothing
If tabPagesActiveControl.TryGetValue(e.TabPageIndex, ctrl) Then
BeginInvoke(New Action(Sub() Me.ActiveControl = ctrl))
End If
End Sub
End Class
C# Version:
(assume tabControl1 is the name of the TabControl instance)
public partial class SomeForm : Form
{
private Dictionary<int, Control> tabPagesActiveControl = new Dictionary<int, Control>();
// [...]
// This method is called each time a Control becomes the ActiveControl
protected override void UpdateDefaultButton()
{
base.UpdateDefaultButton();
if (ActiveControl.Parent is TabPage tp) {
var tabPageIdx = (tp.Parent as TabControl).SelectedIndex;
if (tabPagesActiveControl.Count > 0 && tabPagesActiveControl.ContainsKey(tabPageIdx)) {
tabPagesActiveControl[tabPageIdx] = ActiveControl;
}
else {
tabPagesActiveControl.Add(tabPageIdx, ActiveControl);
}
}
}
private void tabControl1_Selected(object sender, TabControlEventArgs e)
{
if (tabPagesActiveControl.TryGetValue(e.TabPageIndex, out Control ctrl)) {
BeginInvoke(new Action(() => ActiveControl = ctrl));
}
}
}
As mentioned previously Tab_Open sub is used to create a form as tab.
In Main form (MDI) created Dictionary as
Public tabPagesActiveControl As New Dictionary(Of String, Integer)
In each form when the control is focused the value has been added to dictionary as
Private Sub DateTimePicker1_Leave(sender As Object, e As EventArgs) Handles RadioButton1.GotFocus,
DateTimePicker1.GotFocus, ComboBox1.GotFocus, CheckBox1.GotFocus, Button1.GotFocus, TextBox3.GotFocus, TextBox4.GotFocus, RichTextBox1.GotFocus
If Form1.tabPagesActiveControl.ContainsKey(Form1.TabControl1.SelectedTab.Name) Then
Form1.tabPagesActiveControl(Form1.TabControl1.SelectedTab.Name) = Me.ActiveControl.TabIndex
Else
Form1.tabPagesActiveControl.Add(Form1.TabControl1.SelectedTab.Name, Me.ActiveControl.TabIndex)
End If
End Sub
And when the tab is focused:
Private Sub TabControl1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles TabControl1.SelectedIndexChanged
If tabPagesActiveControl.ContainsKey(Me.TabControl1.SelectedTab.Name) Then
Dim Indxval As String = String.Format(tabPagesActiveControl.Item(Me.TabControl1.SelectedTab.Name))
SendKeys.Send("{TAB " & Indxval & "}")
End If
End Sub
As mentioned in the comments it has flaws. Kindly please check and help or do let me know what can be tried.
Finally I solved the issue after struggling for 8 Days :)
As I mentioned earlier I Open the forms as tabs using the Sub Tab_Open mentioned in the question.
Defined or created a new dictionary in MDI form as
Public tabPagesActiveControl As New Dictionary(Of String, Control)
and defined a control variable as
Dim Sel_Control As Control
Now in each form when the control is focused I have the below code to assign the current control alone to the dictionary:
Private Sub All_Focus(sender As Object, e As EventArgs) Handles TBox_Reg_website.GotFocus,
TBox_Reg_To.GotFocus, TBox_Reg_State.GotFocus, TBox_Reg_PinCD.GotFocus, TBox_Reg_PAN.GotFocus, TBox_Reg_office_num.GotFocus,
TBox_Reg_mobile_num.GotFocus, TBox_Reg_GSTIN.GotFocus, TBox_Reg_fax_no.GotFocus, TBox_Reg_email.GotFocus, TBox_Reg_country.GotFocus,
TBox_Reg_Company.GotFocus, TBox_Reg_City.GotFocus, TBox_Reg_Add2.GotFocus, TBox_Reg_Add1.GotFocus, TB_Curr_website.GotFocus,
TB_Curr_state.GotFocus, TB_Curr_RegTo.GotFocus, TB_Curr_Pincd.GotFocus, TB_Curr_Pan.GotFocus, TB_Curr_office_num.GotFocus,
TB_Curr_Mobile_num.GotFocus, TB_Curr_Gstin.GotFocus, TB_Curr_fax_no.GotFocus, TB_Curr_email.GotFocus, TB_Curr_country.GotFocus,
TB_Curr_Company.GotFocus, TB_Curr_city.GotFocus, TB_Curr_add2.GotFocus, TB_Curr_add1.GotFocus,
PICBox_Reg_Logo.GotFocus, MSP_Reg.GotFocus, Label9.GotFocus, Label8.GotFocus, Label7.GotFocus, Label6.GotFocus, Label5.GotFocus,
Label4.GotFocus, Label3.GotFocus, Label2.GotFocus, Label15.GotFocus, Label14.GotFocus, Label13.GotFocus, Label12.GotFocus,
Label11.GotFocus, Label10.GotFocus, Label1.GotFocus,
ChkBx_Upd_Logo.GotFocus, Chkbox_NoLogo.GotFocus
If Form1.tabPagesActiveControl.ContainsKey(Form1.TabControl1.SelectedTab.Name) Then
Form1.tabPagesActiveControl.Remove(Form1.TabControl1.SelectedTab.Name)
End If
Form1.tabPagesActiveControl.Add(Form1.TabControl1.SelectedTab.Name, Me.ActiveControl)
End Sub
and in the MDI form when tab select index changes having the below code:
Private Sub TabControl1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles TabControl1.SelectedIndexChanged
If tabPagesActiveControl.ContainsKey(Me.TabControl1.SelectedTab.Name) Then
Sel_Control = tabPagesActiveControl.Item(Me.TabControl1.SelectedTab.Name)
Sel_Control.Focus()
End If
End Sub
Thanks :)

Auto initialize controls

I've created a custom control that need to be initialized. Actually I have that function to initialize my custom control (called "UserControl_Grille") :
Private Sub Init_Grille()
Me.grilleA.init_traduction(lignesTraduction)
Me.grilleB.init_traduction(lignesTraduction)
Me.grilleC.init_traduction(lignesTraduction)
Me.grilleD.init_traduction(lignesTraduction)
Me.grilleE.init_traduction(lignesTraduction)
Me.grilleF.init_traduction(lignesTraduction)
Me.grilleG.init_traduction(lignesTraduction)
Me.grilleH.init_traduction(lignesTraduction)
End Sub
As you can see it's not very worth it as If a add a new control I have to add it in this function.
So I tried to initialize automatically but it seems that it don't detect any custom control in my form ... :
Private Sub Init_Grille()
For Each grille As UserControl_Grille In Me.Controls.OfType(Of UserControl_Grille)()
grille.init_traduction(lignesTraduction)
Next
End Sub
In debug mode, it direct pass throught the For Each loop. There is any other solution?
You can recursively scroll through all controls.
For example, this sample code will return a list of all Labels in your form:
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
' This list will hold all the labels that we find
Dim results As List(Of Control) = New List(Of Control)
' Start searching for labels at the Form level
FindControls(Me, results)
' See how many labels we have found
MessageBox.Show(results.Count)
End Sub
Private Sub FindControls(parent As Control, ByRef results As List(Of Control))
For Each control As Control In parent.Controls
If TypeOf control Is Label Then
' We found a label so we add it to the results
results.Add(control)
End If
If Not control.Controls Is Nothing Then
' We loop through all sub-controls
FindControls(control, results)
End If
Next
End Sub
End Class
Hope this helps :)

How to set an event for MDI child forms without adding code to each form?

I would like to set the background color for a certain type of control on all child forms that open. I have an MdiParent form that is used to open the other forms within itself. I don't want to add code to each child form as this would be very extensive. This would be used as a theme feature for the application so I would like to have it automatically change the background colors based on logic in the main form. Is there something like a global event that could trigger for all Form.Load events?
So far I have created an event in the Parent form but it doesn't work for nested controls
Private Sub frmMain_MdiChildActivate(sender As Object, e As EventArgs) Handles Me.MdiChildActivate
Dim ParentControl As frmMain = sender
Dim ChildControl = ParentControl.ActiveControl
If ChildControl IsNot Nothing Then
For Each FormControl As Control In ChildControl.Controls
If FormControl.GetType = GetType(GroupBox) Then
RemoveHandler FormControl.Paint, AddressOf PaintBorderlessGroupbox
AddHandler FormControl.Paint, AddressOf PaintBorderlessGroupbox
End If
Next
End If
End Sub
I was able to accomplish this by using Form.MdiChildActivate and adding the event to the appropriate controls based on the Event and EventHandler.
Private Sub frmMain_MdiChildActivate(sender As Object, e As EventArgs) Handles Me.MdiChildActivate
Dim ParentForm As frmMain = sender
Dim ChildForm = ParentForm.ActiveMdiChild
Dim EventName = "Paint"
Dim EventHandlerName = "PaintBorderlessGroupBox"
If ChildForm IsNot Nothing Then
AddEventToControls(ChildForm, GetType(GroupBox), EventName, EventHandlerName)
End If
End Sub
Private Sub AddEventToControls(Control As Control, ControlType As Type, ControlEventName As String, ControlEventMethod As String)
For Each ChildControl In Control.Controls
If ChildControl.GetType = ControlType Then
If ChildControl.Controls.Count > 0 Then
AddEventToControls(ChildControl, ControlType, ControlEventName, ControlEventMethod)
End If
Dim EventMethod = Me.GetType().GetMethod(ControlEventMethod, BindingFlags.NonPublic Or BindingFlags.Instance)
Dim ControlEvent As EventInfo = ControlType.GetEvent(ControlEventName)
Dim del = [Delegate].CreateDelegate(ControlEvent.EventHandlerType, Me, EventMethod)
ControlEvent.RemoveEventHandler(ChildControl, del)
ControlEvent.AddEventHandler(ChildControl, del)
End If
Next
End Sub
The call to AddEventToControls() assigns the handler to the Control and any child controls that it would also apply to. In this case I am setting the Control.Paint event to paint a GroupBox a specific way. This may not be the cleanest method to accomplish this but I was able to create a "Global Event" for all child forms without ever touching the code on each form.
In your parent form, keep a collection of all Child Forms that have been activated. You can then traverse that collection and change the relevant control property for each one.
For Each ChildForm in MyCollection
ChildForm.TextBox.BackColor = Red
Next
Of course:
The ChildForm control has to be accessible by the parent form
The ChildForm has to still exist (i.e. not been closed in the mean
time)
You can't check for ChildForm closure because you are not adding any
code to the ChildForm to signal such an event.
You have to handle the exceptions when you try to change a form that
has been closed.
Much easier to include a method in your ChildForm design for ChangeColour(), whether that method is fired by event or direct call is your design decision. And to include a method to tell the parent form when a ChildForm dies so that it stops looking for it.

Update Label And ProgressBar value from another class invoked in a background worker

hello I have a problem to update a progress bar and a label inside a StatusStrip in the main form.
there are 2 controls in the form inside a StatusStrip:
Progressbar (ToolStripProgressBar)
ProgressLabel (ToolStripStatusLabel)
Basically I have this situation:
Public Class Main
Public Sub TEST(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles TEST.DoWork
Dim tmp as New NAMESPACE1.CLASS2(VALUES)
End Sub
End Class
Namespace NAMESPACE1
Public Class CLASS2
Public Sub New(VALUES)
Main.Progressbar.Value = 15
Main.ProgressLabel.Text = "hello!"
End Sub
End Class
End Namespace
The problem is that text or value of the controls are updated (I see it using breakpoints) in the code but not in the form in which progressbar is always a 0% and label always as nothing.
I think it's an update or refresh problem of the main form. i have tried to do Main.Refresh() and Main.Update() but it does not work anyway.
Thanks in advance.
You have 2 issues in play. The first is that Main is a class name, not a runtime reference or object variable. See Idle_Mind's answer for using Me to get the runtime object reference.
The second problem is that since Class2 is created in DoWork, it is created on the background thread, which will prevent it from accessing UI controls (which are created on the UI thread). You will get an illegal cross thread operation exception (even if you dont see it).
I'd suggest that Class2 does nothing useful which can't be done using the ReportProgress method. Getting rid of it also gets rid of the form reference issue since an event is raised on the same thread as the UI controls:
Private WithEvents bgw As BackgroundWorker
...
' in a button click or whatever starts the worker:
bgw = New BackgroundWorker
bgw.WorkerReportsProgress = True
bgw.RunWorkerAsync(5) ' times to loop
...
Private Sub bgw_DoWork(sender As Object,
e As DoWorkEventArgs) Handles bgw.DoWork
' NOTE
' This code executes on a different thread
' so do not reference UI controls!
' e.Argument is the value passed - amount of work
Dim max As Integer = CInt(e.Argument)
For n As Integer = 1 To max
Threading.Thread.Sleep(250) ' emulates work
' causes the ProgressChanged event to fire:
bgw.ReportProgress(n, String.Format("{0} of {1}", n.ToString, max.ToString))
Next
End Sub
Private Sub bgw_ProgressChanged(sender As Object,
e As ProgressChangedEventArgs) Handles bgw.ProgressChanged
'ProgressChanged fires on the UI thread, so it is safe to
' referenece controls here
TextBox4.Text = e.UserState.ToString
TextBox4.Refresh()
End Sub
Paste the code and you can see the message change in the TextBox. The same would work using your ProgressBar and ProgressLabel.
bgw.ReportProgress(n, arg)
The first argument will map to e.ProgressPercentage in the ProgressChanged event. The second is optional - UserState. I used it to pass a string for illustrative purposes (the form can already know the amount of work since it told the BGW what to do.)
If Class2 has some other purpose, you can use it as long as it is created on the UI thread (in the form) and used on that thread (ie in ProgressChanged event). You also need a method to talk to the controls so you dont have to create a new one each time:
Private myObj As Class2 ' declaration
...
myObj = New Class2(Me) ' instance with frm ref
In class2:
Public Sub Update(value As Integer, msg As String)
frmMain.Progressbar.Value = value
frmMain.ProgressLabel.Text = msg
End Sub
Then in the ProgressChanged event:
myObj.Update(x, y)
Where x and y are the value and message from whereever.
Here's an example of passing a reference to MAIN as suggested by Plutonix. I've intentionally left your pseudo-code style intact:
Public Class MAIN
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
TEST.RunWorkerAsync()
End Sub
Private Sub TEST_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles TEST.DoWork
Dim tmp As New NAMESPACE1.CLASS2(Me, VALUES) ' <-- Form reference being passed via 1st parameter
End Sub
End Class
Namespace NAMESPACE1
Public Class CLASS2
Private frmMain As MAIN
Public Sub New(ByVal frmMain As MAIN, VALUES)
Me.frmMain = frmMain
Me.frmMain.Progressbar.Value = 15
Me.frmMain.ProgressLabel.Text = "hello!"
End Sub
End Class
End Namespace

Raising events from a List(Of T) in VB.NET

I've ported a large VB6 to VB.NET project and while it will compile correctly, I've had to comment out most of the event handlers as to get around there being no array collection for winform objects and so putting the various objects that were in at the collection array into a List object.
For example, in VB6 you could have an array of Buttons. In my code I've got
Dim WithEvents cmdButtons As New List(Of Button)
(and in the Load event, the List is propagated)
Obviously, you can't fire an event on a container. Is there though a way to fire the events from the contents of the container (which will have different names)?
In the Button creation code, the event name is there, but from what I understand the handler won't intercept as the Handles part of the code is not there (commented out).
I'm not exactly sure what you're after, but if you want to be able to add event handlers to some buttons in a container and also have those buttons referenced in a List, you can do something like
Public Class Form1
Dim myButtons As List(Of Button)
Private Sub AddButtonsToList(targetContainer As Control)
myButtons = New List(Of Button)
For Each c In targetContainer.Controls
If TypeOf c Is Button Then
Dim bn = DirectCast(c, Button)
AddHandler bn.Click, AddressOf SomeButton_Click
myButtons.Add(bn)
End If
Next
End Sub
Private Sub SomeButton_Click(sender As Object, e As EventArgs)
Dim bn = DirectCast(sender, Button)
MsgBox("You clicked " & bn.Name)
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' GroupBox1 has some Buttons in it
AddButtonsToList(GroupBox1)
End Sub
End Class