kielou
kielou

Reputation: 437

Why I can't get the selected value?

I have two ComboBox for Employee & PayrollName. on the first ComboBox('PayrollName'), using SelectedValue is fine but when it comes to the next ComboBox I get this error:

Conversion from type 'VB$AnonymousType_11(Of Integer,String)' to type 'Integer' is not valid

I have tried to search for the error but no luck, I can't find even one

My code for loading data to my Employee ComboBox

Dim _list = MyContext.Employees.Where(Function(q) q.Status = True).Select(Function(q) New With
                                                   {
                                                   q.EID,
                                                   .Name = q.Lastname & ", " & q.Firstname
                                                   }).ToList
        Dim list = _list.OrderBy(Function(x) x.Name).ToList()
        With cbxEmployee
            .DataSource = list.ToList
            .DisplayMember = "Name"
            .ValueMember = "EID"
        End With

My code for getting the SelectedValue

Dim EmployeeID As Integer = cbxEmployee.SelectedValue

Why I can't get the selected value? Sorry I am not that good in english

Upvotes: 0

Views: 468

Answers (2)

Joel Coehoorn
Joel Coehoorn

Reputation: 416179

The first statement in the code includes this lambda expression:

Function(q) New With
   {
   q.EID,
   .Name = q.Lastname & ", " & q.Firstname
   }

It generates an anonymous type with an Integer field (EID) and a String field (Name). That's the VB$AnonymousType_11(Of Integer,String) you see in the error message. These values are assigned to the combobox, and so when you look at the SelectedValue for the ComboBox, that's the kind of value you're working with.

So you need to do this:

Dim EmployeeID As Integer = cbxEmployee.SelectedValue.EID

EVEN BETTER

That only works because Option Strict is turned off, and that's very bad. It leads to all kinds of runtime errors. You should turn Option Strict on. That will seem to raise a bunch of new errors is you code, but every single one is really a little time bomb waiting to go off. This gives you the chance to fix those errors now, before they cause a problem for you users. You'll end up with better, faster code, that's easier to maintain.

In this case, that might mean defining a Class for these list objects, which seems like a big deal but it's really only four lines of code:

Public Class EmployeeListItem
    Public Property EID As Integer
    Public Property Name As String
End Class

Then I would further set the DisplayMember and ValueMember items before assigning the DataSource. Combine with other fixes, and you get this:

Dim list = MyContext.Employees.
        Where(Function(q) q.Status = True).
        Select(Function(q) New EmployeeListItem With
                {
                    q.EID,
                    .Name = q.Lastname & ", " & q.Firstname
                 }).
        OrderBy(Function(x) x.Name)

With cbxEmployee
    .DisplayMember = "Name"
    .ValueMember = "EID"
    .DataSource = list
End With

Notice I never had to call ToList(). This reduces memory use, and in some cases can make the code greatly more efficient.

Then, when using the value, you want to cast it, like this:

Dim EmployeeID As Integer = DirectCast(cbxEmployee.SelectedValue, EmployeeListItem).EID

Upvotes: 2

the_lotus
the_lotus

Reputation: 12748

Try turning Option Strict On. SelectedValue isn't an integer and can't be directly inserted in an integer. In this case, it is returning the object of the AnonymousType that you created. You would need decided .Name or .EID

Upvotes: 0

Related Questions