Reputation: 382
I have a structure for example:
Structure User
Dim Name as string
Dim ID as Short
Dim Email as string
End Structure
Now the main array declaration is : Dim Client as new list of User
This new list of array holds all the records. Now how to do the following without using loop such as :
1) I need to populate all distinct name into combo box. If it was string array I could have done
Combobox1.addrange(tmpstring.distinct.toarray)
However because this is a structure of a type (e.g. user) what to do ?
2) How to populate only one set of field data into array using linq. For e.g. if I do Dim A = from b in Client where b.id>0 ' then all array items are returned. How to get only id ?
Thank you.
Upvotes: 0
Views: 453
Reputation: 32248
A List(Of Class) (a reference type) is more flexible than a Structure (a value type).
Using a List(Of Structure):
Dim Clients As New List(Of User)
Structure User
Dim Name As String
Dim ID As Short
Dim Email As String
End Structure
'Add some elements to it
Clients.Add(New User With {.Name = "User1", .ID = 1, .Email = "Email1"})
Clients.Add(New User With {.Name = "User2", .ID = 2, .Email = "Email2"})
Clients.Add(New User With {.Name = "User3", .ID = 3, .Email = "Email3"})
To fill up a ComboBox list, you could:
'Fill it with the whole list
ComboBox1.Items.AddRange(Clients.Select(Function(c) c.Name).ToArray)
'Or filter it using a range of values
Dim SublistClient As New List(Of User)
SublistClient.AddRange(Clients.Select(Function(c) c).Where(Function(c) (c.ID > 1 And c.ID < 3)))
ComboBox1.Items.AddRange(SublistClient.Select(Function(c) c.Name).ToArray)
To get the Item values when a User selects it from the list:
Private Sub ComboBox1_SelectionChangeCommitted(sender As Object, e As EventArgs) Handles ComboBox1.SelectionChangeCommitted
Dim SelectedUser As User = Clients(ComboBox1.SelectedIndex)
Console.WriteLine("Name: {0}, ID: {1}, Email: {2}", SelectedUser.Name, SelectedUser.ID, SelectedUser.Email)
End Sub
Using a List(Of Class)
Dim Clients As New List(Of User)
Class User
Public Property Name As String
Public Property ID As Short
Public Property Email As String
End Class
'You can add items to the list in the same way, nothing will change here
Clients.Add(New User With {.Name = "User1", .ID = 1, .Email = "Email1"})
Clients.Add(New User With {.Name = "User2", .ID = 2, .Email = "Email2"})
Clients.Add(New User With {.Name = "User3", .ID = 3, .Email = "Email3"})
Now you can fill you ComboBox using its .DataSource
property
'Add the whole List as the ComboBox `.DataSource`
ComboBox1.DataSource = Clients
'Or filter it using a range of values
ComboBox1.DataSource = (Clients.Select(Function(c) c).Where(Function(c) (c.ID > 1 And c.ID < 3))).ToList()
'Or from a specific value up or down
ComboBox1.DataSource = (Clients.Select(Function(c) c).Where(Function(c) c.ID > 1)).ToList()
'This gives you extended options when you have to present your data
'or evaluate the result of a choice
ComboBox1.DisplayMember = "Name"
ComboBox1.ValueMember = "ID"
'The user choice is evaluated more or less in the same manner
Private Sub ComboBox1_SelectionChangeCommitted(sender As Object, e As EventArgs) Handles ComboBox1.SelectionChangeCommitted
Dim SelectedUser As User = CType(ComboBox1.SelectedItem, User)
Console.WriteLine("Name: {0}, ID: {1}, Email: {2}", SelectedUser.Name, SelectedUser.ID, SelectedUser.Email)
End Sub
Upvotes: 1
Reputation: 819
1) I am not that familiar with VB, so here is the solution in C#:
var names = Client
.Select(user => user.Name)
.Distinct();
Telerik Code Converter converts this to:
Private names = Client.[Select](Function(user) user.Name).Distinct()
2) If I understand you right, you want to have an array containing the ids? You should extend your query to:
Dim A = from b in Client
where b.id>0
select b.id
Upvotes: 1