Getting Installed Steam Games From Registry - vb.net

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

Related

Get a value by index from combobox class

i'm approaching to vbnet from vb6 and i'm triyng to get value from combobox using a class which contains the values i stored in.
here is the class
Private m_ItemText As String
Private m_ItemIndex As Int32
Public Sub New(ByVal strItemText As String, ByVal intItemIndex As Int32)
m_ItemText = strItemText
m_ItemIndex = intItemIndex
End Sub
Public ReadOnly Property ItemIndex() As Int32
Get
Return m_ItemIndex
End Get
End Property
Public ReadOnly Property ItemText() As String
Get
Return m_ItemText
End Get
End Property
I use this method charge the combobox
ComboBox2.Items.Add(New clsComboBoxItem("sometext", 1))
ComboBox2.Items.Add(New clsComboBoxItem("sometext 2", 2))
ComboBox2.Items.Add(New clsComboBoxItem("sometext", 3))
and this on combobox.selectedindexchanged
If ComboBox2.SelectedItem.GetType.ToString = itmCombo.GetType.ToString Then
itmCombo = CType(ComboBox2.SelectedItem, clsComboBoxItem)
MessageBox.Show("Item Text=" & itmCombo.ItemText & " and ItemIndex=" & CStr(itmCombo.ItemIndex))
End If
Can anyone tell help me to understand how get an element by his index stored in the class? Eg writing '2' into a text box, the combo box sould be show "sometext2".
Suppose i want to expand the class adding some values, like m_ItemText2,m_ItemText3 etc, i would learn a method to get all of theese values.
I hope I was clear
Thanks in advance
If you have a DataSource set to a DataTable for your ComboBox, just set the DisplayMember and ValueMember. My test ComboBox is set to DropDownList.
Private Sub FillComboBox()
Dim dt As New DataTable
Using con As New SqlConnection(ConStr),
cmd As New SqlCommand("Select FlavorID,FlavorName From Flavors", con)
con.Open()
Using reader = cmd.ExecuteReader
dt.Load(reader)
End Using
End Using
ComboBox1.DisplayMember = "FlavorName"
ComboBox1.ValueMember = "FlavorID"
ComboBox1.DataSource = dt
End Sub
To display the the values
To display the Text cast to DataRowView (that is the object that is in the Item), provide the field you want and call ToString.
Private Sub ComboBox1_SelectionChangeCommitted(sender As Object, e As EventArgs) Handles ComboBox1.SelectionChangeCommitted
MessageBox.Show(ComboBox1.SelectedValue.ToString)
MessageBox.Show(DirectCast(ComboBox1.SelectedItem, DataRowView)("FlavorName").ToString)
End Sub
If you are adding items one by one, you can still set the DisplayMember and ValueMember.
'https://stackoverflow.com/questions/38206678/set-displaymember-and-valuemember-on-combobox-without-datasource
Private Sub SomeFormsLoadEvent()
ComboBox1.Items.Add(New KeyValuePair(Of String, Integer)("Ultra-fast", 600))
ComboBox1.Items.Add(New KeyValuePair(Of String, Integer)("Fast", 300))
ComboBox1.Items.Add(New KeyValuePair(Of String, Integer)("Medium", 150))
ComboBox1.Items.Add(New KeyValuePair(Of String, Integer)("Slow", 75))
ComboBox1.DisplayMember = "Key"
ComboBox1.ValueMember = "Value"
ComboBox1.DataSource = ComboBox1.Items
End Sub
I found it a bit more complicated to display the text. I had to cast the item to its underlying type (KeyValuePair) then ask for the Key value.
Private Sub ComboBox1_SelectionChangeCommitted(sender As Object, e As EventArgs) Handles ComboBox1.SelectionChangeCommitted
MessageBox.Show(ComboBox1.SelectedValue.ToString)
MessageBox.Show(DirectCast(ComboBox1.SelectedItem, KeyValuePair(Of String, Integer)).Key)
End Sub
As I understand it you want to store values in a class and display and access them through the combobox. How about this approach:
The class for the values:
Public Class clsValues
Private lstItemTexts As New List(Of String)
Public ReadOnly Property AllValues As List(Of String)
Get
Return lstItemTexts
End Get
End Property
'To initialize class with empty list, items can be added with AddItems
Public Sub New()
End Sub
'To initialize class with items, items can still be added with AddItems
Public Sub New(lstItemTexts As List(Of String))
Me.lstItemTexts = lstItemTexts
End Sub
Public Sub AddItem(item As String)
Me.lstItemTexts.Add(item)
End Sub
Public Function GetItemByIndex(index As Integer) As String
Return lstItemTexts(index)
End Function
Public Function GetIndexByItem(item As String) As Integer
Return lstItemTexts.IndexOf(item)
End Function
End Class
You can declare it and fill values like this:
Private Values As New clsValues()
Values.AddItem("Some Text 1")
Values.AddItem("Some Text 2")
or
Private Values As New clsValues(New List(Of String)({"Some Text 1", "Some Text 2"}))
to get a value from combobox
Private Sub ComboBox2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox2.SelectedIndexChanged
MessageBox.Show(Values.GetItemByIndex(ComboBox2.SelectedIndex))
End Sub
What #Mary stated is true the ComboBox has values that are useful SEE CODE BELOW
Change gvTxType to be a TextBox to see results when you click on the tvTxType
Private Sub cbTxType_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cbTxType.SelectedIndexChanged
If cbTxType.SelectedIndex > -1 Then
'Dim sindex As Integer
'sindex = cbTxType.SelectedIndex
'Dim sitem As String
sitem = CType(cbTxType.SelectedItem, String)
'MsgBox("You Selected " & sitem)
'Index is ZERO based
gvTxType = sitem
End If
End Sub

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.

How to filter a list of generic objects

I have find the code to implement a SortableBindingList that extends of BindingList and it theoretically let sort and filter a list of generic objects.
It works perfectly sorting the list but I can not get filtering.
The filter code is as follows
Protected Sub UpdateFilter()
_isSorted = False 'remove sort.
Try
'We filter on the entire collection
Dim filtered = _originalData.AsQueryable()
If Not String.IsNullOrEmpty(_filter) Then filtered = filtered.Where(_filter)
Dim filteredResult = filtered.ToList()
Items.Clear()
If filteredResult IsNot Nothing AndAlso filteredResult.Count > 0 Then
For Each tItem As T In filtered
Items.Add(tItem)
Next
End If
Catch
'Reset the list
Items.Clear()
For Each tItem As T In _originalData
Items.Add(tItem)
Next
'Rethrow the error
Throw
Finally
OnListChanged(New ListChangedEventArgs(ListChangedType.Reset, -1))
End Try
End Sub
The problem is that the following example receive like a filter a string in the clause where but the compile trhow an error since it wait a function
I don't know how to resolve this
Sorry if you do not understand well. I do not speak English well
You need to pass a predicate. I hope this example will guide you.
Private Function AddFilter(list As List(Of String), filter As Func(Of String, Integer, Boolean)) As List(Of String)
Dim l As IEnumerable(Of String) = Nothing
If Not IsNothing(filter) Then
l = list.Where(filter)
End If
Return l.ToList
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim A As New List(Of String) From {"Mathew", "Mark", "Luke", "John"}
Dim predicate As Func(Of String, Integer, Boolean) = Function(str, index) str.StartsWith("M")
Dim FilteredList = AddFilter(A, predicate)
For Each s As String In FilteredList
Debug.Print(s)
Next
End Sub
There is an answer in some post that recommend this.
You can use Dynamic Linq:
Dim filter As String = "property1>10 and property2 like 'anystring' or property3<=25".
Dim results = Elements.Where(filter).
But I don't know how to use dinamic linq

vb.net - combo box always select the first value

Good day, Can anyone help me with this problem. I have two a combo box for months(01-12) for monthstart and monthend. Now, everytime I select October(10), the value it show is 01. Sorry. I am new in vb.
Is there any alternative way to do this? Any suggestions?
Thanks.
Private Sub ValueComboxformonth()
Dim comboSource As New Dictionary(Of String, String)()
comboSource.Add("01", "January")
comboSource.Add("02", "February")
comboSource.Add("03", "March")
comboSource.Add("04", "April")
comboSource.Add("05", "May")
comboSource.Add("06", "June")
comboSource.Add("07", "July")
comboSource.Add("08", "August")
comboSource.Add("09", "September")
comboSource.Add("10", "October")
comboSource.Add("11", "November")
comboSource.Add("12", "December")
cmbAppliedMonthStart.DataSource = New BindingSource(comboSource, Nothing)
cmbAppliedMonthStart.DisplayMember = "Value"
cmbAppliedMonthStart.ValueMember = "Key"
cmbAppliedMonthEnd.DataSource = New BindingSource(comboSource, Nothing)
cmbAppliedMonthEnd.DisplayMember = "Value"
cmbAppliedMonthEnd.ValueMember = "Key"
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
ValueComboxformonth()
Dim monthkeystart As String = DirectCast(cmbAppliedMonthStart.SelectedItem, KeyValuePair(Of String, String)).Key
Dim monthvaluestart As String = DirectCast(cmbAppliedMonthStart.SelectedItem, KeyValuePair(Of String, String)).Value
Dim monthkeyend As String = DirectCast(cmbAppliedMonthEnd.SelectedItem, KeyValuePair(Of String, String)).Key
Dim monthvalueend As String = DirectCast(cmbAppliedMonthEnd.SelectedItem, KeyValuePair(Of String, String)).Value
End Sub
The value of monthkeystart is 01
The value of monthvaluestart is January
This is due to you calling the ValueComboxformonth method before reading the values. That method resets the datasource for the combo-boxes, and it defaults to the first value.
Try moving that call to the constructor (New method) of the form.
Public Sub New()
...
ValueComboxformonth()
End Sub

Sharing a List of(String) between Private Sub

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)