|
-
Apr 12th, 2019, 02:50 PM
#1
Thread Starter
Junior Member
Problem declaring list to have form level scope.
Hi,
N00b issue; I don’t seem to be able to give the correct scope when defining a collection/list.
The list holds a group of references to textboxes.
Code:
Dim TBDec1 As New List(Of TextBox)() From {TBDecMsg1B7, TBDecMsg1B6, TBDecMsg1B5, TBDecMsg1B4, TBDecMsg1B3, TBDecMsg1B2, TBDecMsg1B1, TBDecMsg1B0}
The program works if this is declared within each procedure that requires it.
In an attempt to tidy up, I wish to declare it with a wider scope. I assumed form level would suffice and placed the follow, immediately after the ‘Public Class Form1’ line.
Code:
Private TBDec1 As New List(Of TextBox)() From {TBDecMsg1B7…. Etc
I tried DIM, PRIVATE
I also tried (badly) to create a module to hold this ‘global’ variable…no luck as it clearly had no knowledge of the textboxes references by the declaration.
Each time I run, I get;
Code:
System.NullReferenceException: 'Object reference not set to an instance of an object.'
Clearly, when a variable is being used to retrieve an item from the list and its not able to find the list, even though I though I have it declared and at a quite broad level.
Am I missing something obvious here ?
How would you declare a list of textboxes at a broad level that will cover most of my 'windows forms' project?
Thanks for any guidance. - please excuse incorrect use of terminology.
-
Apr 12th, 2019, 03:10 PM
#2
Re: Problem declaring list to have form level scope.
Your textboxes don't exist if you declare them at form level. Form level variables are processed before the form's InitializeComponent method. All of your form controls are created in InitializeComponent...
Code:
Public Class Form1
Dim TBDec1 As New List(Of TextBox)
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
TBDec1.AddRange(New TextBox() {TBDecMsg1B7, TBDecMsg1B6, TBDecMsg1B5, TBDecMsg1B4, TBDecMsg1B3, TBDecMsg1B2, TBDecMsg1B1, TBDecMsg1B0})
End Sub
End Class
- Coding Examples:
- Features:
- Online Games:
- Compiled Games:
-
Apr 12th, 2019, 03:29 PM
#3
Re: Problem declaring list to have form level scope.
The other place you could put this is in the constructor for the form (Sub New), which is typically found in the .designer.vb file, unless you have created your own constructor.
There probably isn't all that much difference between the two, but the constructor is run when you create the form, whereas the Load event is raised when you show the form. Typically showing follows closely after creation, but it doesn't have to, which can be convenient.
My usual boring signature: Nothing
 
-
Apr 12th, 2019, 03:38 PM
#4
Thread Starter
Junior Member
Re: Problem declaring list to have form level scope.
oh, Good to know, thanks. J.
-
Apr 13th, 2019, 09:27 AM
#5
Re: Problem declaring list to have form level scope.
Another idea is if you want all TextBox controls on a form to be in the List(Of TextBox) including those in panels and or group boxes add the following code module to the project.
Code:
Public Module ControlExtensions
''' <summary>
''' Provides access to all controls on a form including
''' controls within containers e.g. panel and group box etc.
''' </summary>
''' <typeparam name="T"></typeparam>
''' <param name="control"></param>
''' <returns></returns>
<Runtime.CompilerServices.Extension>
Public Iterator Function Descendants(Of T As Class)(control As Control) As IEnumerable(Of T)
For Each child As Control In control.Controls
Dim currentChild = TryCast(child, T)
If currentChild IsNot Nothing Then
Yield currentChild
End If
If child.HasChildren Then
For Each descendant As T In child.Descendants(Of T)()
Yield descendant
Next
End If
Next
End Function
End Module
Then to use it for all TextBox controls on a form.
Code:
Public Class Form1
Private TextBoxList As New List(Of TextBox)
Public Sub New()
InitializeComponent()
TextBoxList = Descendants(Of TextBox).ToList()
For Each textBox As TextBox In TextBoxList
AddHandler textBox.TextChanged, AddressOf GeneralTextBox_TextChanged
Next
End Sub
Private Sub GeneralTextBox_TextChanged(sender As Object, e As EventArgs)
Console.WriteLine(
$"Value for {CType(sender, TextBox).Name} is '{CType(sender, TextBox).Text}'")
End Sub
End Class
To get nothing off the form directly, get TextBox controls in a single panel and a single group box.
Code:
Public Sub New()
InitializeComponent()
TextBoxList = Panel1.Descendants(Of TextBox).ToList()
TextBoxList.AddRange(GroupBox1.Descendants(Of TextBox))
For Each textBox As TextBox In TextBoxList
AddHandler textBox.TextChanged, AddressOf GeneralTextBox_TextChanged
Next
End Sub
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|