Sharing a List of(String) between Private Sub - vb.net

In my code I basically read a textbox and put each line into a list (Of String) Dim "testblock" in code below
From there I create another list (of string) and split each line whenever a space is found. Dim "block" in code below
Now I want to be able to access that list from anywhere in the project.
How do I go about sharing a List of(String) between Private Sub such as form buttons?
Private Sub PhaseCodeBTN_Click(sender As Object, e As EventArgs) Handles PhaseCodeBTN.Click
Dim testblock As New List(Of String)
Dim lines As String() = TextBox1.Text.Split(New String() {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries)
Dim block As New List(Of String)
For Each l As String In lines
testblock.Add(l)
Dim words As String() = BlockCodeBox.Text.Split(" ")
For Each splitword As String In words
block.Add(splitword)
Next
Next
BlockCodeBox.Text = testblock(BlockNumBox.Text)
WordCmdBox.Text = block(WordNumBox.Text)
End Sub
Private Sub PhaseBlackBTN_Click(sender As Object, e As EventArgs) Handles PhaseBlackBTN.Click
WordCmdBox.Text = block(WordNumBox.Text)
End Sub

Create a Public Shared Class with your List(Of String) there to use it anywhere in the project:
Public Shared Class DataHolder
Private _block As New List(Of String)
Public Property Block As List(Of String)
Get
Return _block
End Get
Set
_block = value
End Set
End Property
End Class
Example:
Either simply use DataHolder.Block.Add(splitword) OR following steps:
Declare a class variable block to use it in entire class:
Private block As List(Of String)
Initialize it in some suitable function / event-handler like Form_Load:
block = DataHolder.Block
Do the operation:
block.Add(splitword)

Related

Passing list to function as parameter

I have a function that will perform work on a list, but I cannot get it to accept more than one datatype. For example:
Public Sub PopulateListBox (objectList as List(of VariantType), ListboxToPopulate as Listbox)
listboxToPopulate.Items.Clear() 'clears the items in the listbox
For Each item In objectList
listboxToPopulate.Items.Add(item.ToString)
Next
End
The problem is that I have lists of different classes, like employee, building address, etc. I cannot pass a List(Of EmployeeClass) because it says it cannot be converted to List(Of VariantType). I have also tried List(Of Object) and the same result.
I will demonstrate the use by first showing you a sample class.
Public Class Coffee
Public Property ID As Integer
Public Property Name As String
Public Property Type As String
Public Sub New(iid As Integer, sname As String, stype As String)
ID = iid
Name = sname
Type = stype
End Sub
Public Overrides Function ToString() As String
Return Name
End Function
End Class
I added a parameterized constructor just to make it easy to get a fully populate Coffee. You need to add the .ToString override so the list box will know what to display.
Here is where my List(Of Coffee) comes from.
Private Function FillCoffeeList() As List(Of Coffee)
Dim CoffeeList As New List(Of Coffee)
Using cn As New SqlConnection(My.Settings.CoffeeConnection),
cmd As New SqlCommand("Select Top 10 ID, Name, Type From Coffees;", cn)
cn.Open()
Using reader = cmd.ExecuteReader
Do While reader.Read
Dim c As New Coffee(reader.GetInt32(0), reader.GetString(1), reader.GetString(2))
CoffeeList.Add(c)
Loop
End Using
End Using
Return CoffeeList
End Function
As commented by Hans Passant, change the datatype of objectList to IEnumerable(Of Object).
Public Sub PopulateListBox(objectList As IEnumerable(Of Object), ListboxToPopulate As ListBox)
ListboxToPopulate.Items.Clear() 'clears the items in the listbox
For Each item In objectList
ListboxToPopulate.Items.Add(item)
Next
End Sub
Now I can pass a List(Of Coffee) to the PopulateListBox method.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim CList = FillCoffeeList()
PopulateListBox(CList, ListBox1)
End Sub
I can access the properties of the underlying type be casting.
Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged
Dim t = ListBox1.SelectedItem.GetType
Select Case t.Name
Case "Coffee"
Dim c = DirectCast(ListBox1.SelectedItem, Coffee)
TextBox1.Text = c.ID.ToString
TextBox2.Text = c.Type
End Select
End Sub
You can add additionsl cases depending on what types you are expecting. There is probably a better way to do this.

Getting Installed Steam Games From Registry

Can someone help me with this error I'm getting? Error14 'Using' operand of type 'System.Collections.Generic.List(Of String)' must implement 'System.IDisposable'
Public Function GetInstalledGames() As Object
Dim enumerator As IEnumerator(Of String) = Nothing
Dim list As List(Of String) = Directory.GetFiles(String.Concat(Me.SteamPath, "\steamapps")).ToList()
Using strs As List(Of String) = New List(Of String)()
enumerator = list.Distinct().GetEnumerator()
While enumerator.MoveNext()
Dim current As String = enumerator.Current
If (current.Contains("appmanifest_") And current.Contains(".acf")) Then
strs.Add(Path.GetFileName(current).Replace("appmanifest_", "").Replace(".acf", ""))
End If
End While
End Using
Return strs
End Function
Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs)
Dim enumerator As IEnumerator(Of String) = Nothing
Me.tbOutput.Text = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
Me.SteamPath = Conversions.ToString(Me.GetSteamPath())
Using installedGames As List(Of String) = DirectCast(Me.GetInstalledGames(), List(Of String))
enumerator = installedGames.Distinct().GetEnumerator()
While enumerator.MoveNext()
Dim current As String = enumerator.Current
Me.lbGames.Items.Add(current)
End While
End Using
End Sub
Stop writing explicit enumerator loops for no reason
Make your functions return types that make sense instead of Object
Don’t sprinkle Using into code without knowing what it does
Pass data between functions through arguments, not class fields
Private Shared Function GetInstalledGames(steamPath As String) As IEnumerable(Of String)
Dim result As New List(Of String)
For Each name In Directory.GetFiles(Path.Combine(steamPath, "steamapps"))
If name.Contains("appmanifest_") AndAlso name.Contains(".acf") Then
result.Add(Path.GetFileNameWithoutExtension(name).Replace("appmanifest_", ""))
End If
Next
Return result
End Function
Private Sub Form1_Load(sender As Object, e As EventArgs)
Me.tbOutput.Text = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
Dim steamPath As String = Me.GetSteamPath()
For Each current In GetInstalledGames(steamPath).Distinct()
Me.lbGames.Items.Add(current)
Next
End Sub

How to return specific properties of a custom vb.net object

I'm trying to generate a list of all of the TableName and FieldName properties for a custom object type called LxTextBox. I've gotten as far as generating a list of all of the LxTextBox names on my form, but I can't figure out a way to call the properties of the custom object... I've been looking into System.Reflection, but I haven't ever used it. Additionally, I'm returning the list to a RichTextBox while I'm testing this out, but ultimately, I need to return each objects properties as a data row. Example:
ObjectName Table Field
---------------------------------------
LxTextBox23 SomeTbl SomeFld
Here's my code to return the list - updated based on #OneFineDay...
Imports System.Collections.Generic
Imports Application.UDF.Controls
Public Class MeasurementsControl
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim textBoxList As New List(Of Control)
Dim customTbs = GetAllControls(Me)
Dim sb As New System.Text.StringBuilder
For index As Integer = 0 To customTbs.Count - 1
sb.Append(customTbs.Item(index).TableName & "." & customTbs.Item(Index).FieldName & System.Environment.NewLine)
Next
RichTextBox1.Text = sb.ToString
End Sub
Private Function GetAllControls(ByVal searchWithin As Control) As List(Of LxTextbox)
Dim returnList As List(Of LxTextbox) = Nothing
If searchWithin.HasChildren Then
returnList = searchWithin.Controls.OfType(Of LxTextbox).ToList
For Each ctrl As Control In searchWithin.Controls
returnList.AddRange(GetAllControls(ctrl))
Next
End If
Return returnList
End Function
End Class
I made the changes suggested and I'm throwing an error: OfType is not a member of System.Windows.Forms.Control.ControlCollection
FYI - Adding Imports System.Linq did not fix the error.
You are boxing it into a Control the object from where it derives, where you're custom properties cannot be found. You can cast it right from the control collection.
Dim customTbs = GetAllControls(Me)
'recursive function
Private Function GetAllControls(ByVal searchWithin As Control) As List(Of LxTextbox)
Dim returnList As List(Of LxTextbox) = Nothing
returnList = searchWithin.Controls.OfType(Of LxTextbox).ToList
If searchWithin.HasChildren Then
For Each ctrl As Control In searchWithin.Controls
Dim ctrls = GetAllControls(ctrl)
If Not ctrls Is Nothing Then returnList.AddRange(ctrls)
Next
End If
Return returnList
End Function

sort results (find method) not working

I am using ArcGIS. I am trying to sort the data manually after its found. I created a property class and loop through a Tlist to scrub unwanted data. However right before it binds to the data grid, I receive a cast error. I assume something is coming back null. Am I missing something??
Public Class temp
Public Sub New()
End Sub
Public Property DisplayFieldName As String
Public Property Feature As ESRI.ArcGIS.Client.Graphic
Public Property FoundFieldName As String
Public Property LayerId As Integer
Public Property LayerName As String
Public Property Value As Object
End Class
Public Class templst
Public Sub New()
Dim findresult = New List(Of temp)
End Sub
Private _findresult = findresult
Public Property findresult() As List(Of temp)
Get
Return _findresult
End Get
Set(ByVal value As List(Of temp))
_findresult = value
End Set
End Property
End Class
Private Sub FindTask_Complete(ByVal sender As Object, ByVal args As FindEventArgs)
Dim newargs As New templst() 'puts Tlist (temp) into property
Dim templistNUMONLY As New List(Of temp) 'Tlist of temp
For Each r In args.FindResults 'class in compiled dll.
If Regex.Match(r.Value.ToString, "[0-9]").Success Then
templistNUMONLY.Add(New temp() With {.LayerId = r.LayerId,
.LayerName = r.LayerName,
.Value = r.Value,
.FoundFieldName = r.FoundFieldName,
.DisplayFieldName = r.DisplayFieldName,
.Feature = r.Feature})
End If
Next
newargs.findresult = templistNUMONLY
Dim sortableView As New PagedCollectionView(newargs.findresult)
FindDetailsDataGrid.ItemsSource = sortableView 'populate lists here
End Sub
BIND TO GRID HERE: (Error here)
Private Sub FindDetails_SelectionChanged(ByVal sender As Object, ByVal e As SelectionChangedEventArgs)
' Highlight the graphic feature associated with the selected row
Dim dataGrid As DataGrid = TryCast(sender, DataGrid)
Dim selectedIndex As Integer = dataGrid.SelectedIndex
If selectedIndex > -1 Then
'''''''''''''''''CAST ERROR HERE:
Dim findResult As FindResult = CType(FindDetailsDataGrid.SelectedItem, FindResult)
You populate FindDetailsDataGrid with objects of type temp, but you try to cast it to type FindResult instead. You should do:
Dim selectedTemp As temp = CType(FindDetailsDataGrid.SelectedItem, temp)
'*Create find result from selected temp object here*

Do local variables in shared method work like static variable in C?

Will the list in this shared method keep its state throughout the life of the method? Or will a new list be created every time this method is called?
Protected Shared Function newResxNodes(ByVal newName As String, ByVal newValue As String, Optional ByVal newComment As String = "") As List(Of ResXDataNode)
Dim newResxNodesList As List(Of ResXDataNode) = New List(Of ResXDataNode)
Dim newResxNode As ResXDataNode = New ResXDataNode(newName, newValue)
If newComment <> String.Empty Then
newResxNode.Comment = newComment
End If
newResxNodesList.Add(newResxNode)
Return newResxNodesList
End Function
No, It does not work like static variables in C. It will be a new list for every call. If you want to retain the list and list items, create a shared class field.
I've done a test and it returns 3 lines.
Module Module1
Class b
Public Sub New()
Console.WriteLine("New")
End Sub
End Class
Class a
Public Shared Sub Test()
Dim c As b = New b
End Sub
End Class
Sub Main()
a.Test()
a.Test()
a.Test()
Console.ReadLine()
End Sub
End Module