9 Replies - 15194 Views - Last Post: 03 October 2011 - 12:49 AM Rate Topic: -----

#1 Ahleki  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 55
  • Joined: 01-June 10

Value of type ListItem cannot be converted to 'Valuepair'

Posted 27 September 2011 - 03:43 AM

Hi am trying to get an item from a combo box by using a class (ValuePair) to add items to the combo box
This is the code of the class
Public Class ValuePair

    Public Value As Object
    Public Description As String
    Public Reference As String

    Public Sub New(ByVal NewValue As Object, ByVal NewDescription As String, Optional ByVal NewRef As String = "")
        Value = NewValue
        Description = NewDescription
        Reference = NewRef
    End Sub

    Public Property UnderlyingValue() As String
        Get
            Return Value
        End Get
        Set(ByVal Thisvalue As String)
            Value = Thisvalue
        End Set
    End Property

    Public Overrides Function ToString() As String
        Return Description
    End Function
End Class


And this is how am adding items to the combobox
    Public Sub PopulateCombo()
        cboClientID.Items.Clear()

        Dim cmdDevices As SqlCommand = New SqlCommand("GetDevices", DBConnection.MyConnObj)
        cmdDevices.CommandType = CommandType.StoredProcedure

        With cmdDevices
            .Parameters.Add("@ProductID", SqlDbType.VarChar).Value = ""
            .Parameters.Add("@ClientID", SqlDbType.VarChar).Value = "sa"
            .Parameters.Add("@RecordDeleted", SqlDbType.Bit).Value = 0
        End With
        dtClients.Load(cmdDevices.ExecuteReader())

        For Each dr As DataRow In dtClients.Rows
            cboClientID.Items.Add(New ValuePair(dr.Item("Client_ID"), dr.Item("Client_Name")).ToString)
        Next
    End Sub



So the error am getting is occuring at selectedindexchanged event as shown below:
    Protected Sub cboClientID_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles cboClientID.SelectedIndexChanged
        If cboClientID.SelectedIndex >= 0 Then
            Dim MySubItem As ValuePair
            Dim ClientID As String
            MySubItem=(cboClientID.Items(cboClientID.SelectedIndex) 'error occuring at this point
            'err decription: Value of type 'System.Web.UI.WebControls.ListItem' cannot be converted to 'ValuePair'.
            ClientID = MySubItem.Value
            txtClientName.Text = ClientID
        End If
    End Sub



Is This A Good Question/Topic? 0
  • +

Replies To: Value of type ListItem cannot be converted to 'Valuepair'

#2 Frinavale  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 205
  • View blog
  • Posts: 776
  • Joined: 03-June 10

Re: Value of type ListItem cannot be converted to 'Valuepair'

Posted 27 September 2011 - 08:09 AM

You should be using ListItems in a ComboBox.

You can create your ValuePairs in order to cache the data retrieved from the database.
Once you've done that you will have to create ListItems that get added to the ComboBox...a ComboBox doesn't know how use your ValuePair class so of course it is going to throw an exception.

One solution that comes to the top of my head would be to implement the ability to cast a ValuePair into a ListItem.

-Frinny
Was This Post Helpful? 0
  • +
  • -

#3 Ahleki  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 55
  • Joined: 01-June 10

Re: Value of type ListItem cannot be converted to 'Valuepair'

Posted 28 September 2011 - 06:27 AM

BTW this code was working perfectly in VB.Net.The problem is the ASP.NET combo box does not support the ObjectCollection property whereas that of Windows Form works.
So is there any way I can achieve this.
Thanks.
Was This Post Helpful? 0
  • +
  • -

#4 Frinavale  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 205
  • View blog
  • Posts: 776
  • Joined: 03-June 10

Re: Value of type ListItem cannot be converted to 'Valuepair'

Posted 28 September 2011 - 09:14 AM

Hehe, by the way, ASP.NET has different controls than WinForms controls!

They may "look" the same when rendered but the technologies are completely different: ASP.NET's DropDownList is rendered as an HTML <select> element and the WinForm's ComboBox is rendered using GDI Objects.

The HTML <select> element has <option> children.
The <option> have a "value" attribute and display text that is within the opening and closing tags for this element.

For example, the following is an HTML <select> element with <option> children:
<select>
  <option value="1">Volvo</option>
  <option value="2">Saab</option>
  <option value="3">Mercedes</option>
  <option value="4">Audi</option>
</select>


Now, like I said, ASP.NET has a DropDownList server control that renders as an HTML <select>. This control lets you add and manipulate items in the list using your sever-side code. The reason the DropDownList only takes ListItems is because the ListItems are rendered as the HTML <option> elements. The HTML <option> is very simple and so there are limitations on what the ListItem can do...there's just a "value" and a "text" aspect to the HTML <option> and so there's a "value" and a "text" aspect to the ListItem.

This is the reason why the ASP.NET DropDownList has limitations that the WinForms control does not have. While Microsoft has done a good job at making developers feel comfortable developing in both environments by creating server-controls that act similar in both environments, you cannot expect the controls to be the same. They are different.

-Frinny

This post has been edited by Frinavale: 28 September 2011 - 09:16 AM

Was This Post Helpful? 0
  • +
  • -

#5 Frinavale  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 205
  • View blog
  • Posts: 776
  • Joined: 03-June 10

Re: Value of type ListItem cannot be converted to 'Valuepair'

Posted 28 September 2011 - 01:54 PM

Normally I don't spell out what I was hinting at but today I'm in a strange mood.

So, what I recommended before was to add code that will handle casting the ValuePair type into a ListItem type. To do this you have to implement some code for the CType operator.


This is what your code would look like for the ValuePair class:
Public Class ValuePair

    Public Value As Object
    Public Description As String
    Public Reference As String

 
    Public Sub New(ByVal NewValue As Object, ByVal NewDescription As String, Optional ByVal NewRef As String = "")
        Value = NewValue
        Description = NewDescription
        Reference = NewRef
    End Sub

    Public Property UnderlyingValue() As String
        Get
            Return Value
        End Get
        Set(ByVal Thisvalue As String)
            Value = Thisvalue
        End Set
    End Property

    Public Overrides Function ToString() As String
        Return Description
    End Function
    Public Shared Narrowing Operator CType(ByVal initialData As ListItem) As ValuePair
        Return New ValuePair(initialData.Value, initialData.Text)
    End Operator

    Public Shared Widening Operator CType(ByVal initialData As ValuePair) As ListItem
        Return New ListItem(initialData.Description, initialData.Value)
    End Operator

End Class


I modified your PopulateCombo method to test this out and it works fine:
    Public Sub PopulateCombo()
        cboClientID.Items.Clear()

        'Dim cmdDevices As SqlCommand = New SqlCommand("GetDevices", DBConnection.MyConnObj)'
        'cmdDevices.CommandType = CommandType.StoredProcedure'

        'With cmdDevices'
        '    .Parameters.Add("@ProductID", SqlDbType.VarChar).Value = ""'
        '    .Parameters.Add("@ClientID", SqlDbType.VarChar).Value = "sa"'
        '    .Parameters.Add("@RecordDeleted", SqlDbType.Bit).Value = 0'
        'End With'
        'dtClients.Load(cmdDevices.ExecuteReader())'

        'For Each dr As DataRow In dtClients.Rows'
        '    cboClientID.Items.Add(New ValuePair(dr.Item("Client_ID"), dr.Item("Client_Name")).ToString)'
        'Next'


        For i As Integer = 1 To 10
            cboClientID.Items.Add(New ValuePair(i, String.Format("{0} {1}", "Description for Item", i.ToString)))
        Next
    End Sub


There's another approach that you can take though.
You could convert your Public members into Properties to allow ASP.Net to bind the DropDownList to them. (In my opinion using using Properties is just better programming practice anyways).

Using this approach you would convert the Public members in your ValuePair class into properties like this:
Public Class ValuePair

    'Public Value As Object'
    'Public Description As String'
    'Public Reference As String'

    Private _value As Object
    Private _description As String
    Private _reference As String
    Public Property Value() As Object
        Get
            Return _value
        End Get
        Set(ByVal value As Object)
            _value = value
        End Set
    End Property
    Public Property Description() As String
        Get
            Return _description
        End Get
        Set(ByVal value As String)
            _description = value
        End Set
    End Property
    Public Property Reference() As String
        Get
            Return _reference
        End Get
        Set(ByVal value As String)
            _reference = value
        End Set
    End Property

    Public Sub New(ByVal NewValue As Object, ByVal NewDescription As String, Optional ByVal NewRef As String = "")
        Value = NewValue
        Description = NewDescription
        Reference = NewRef
    End Sub

    Public Property UnderlyingValue() As String
        Get
            Return Value
        End Get
        Set(ByVal Thisvalue As String)
            Value = Thisvalue
        End Set
    End Property

    Public Overrides Function ToString() As String
        Return Description
    End Function
End Class



Then in your PopulateCombo method you would:
  • Create a list of ValuePair objects based on the information retrieved from the database
  • Set the comboClientID.DataSource to this list
  • Set the comboClientID.DataTextField to the property that you want displayed as text (probably the "Description" property)
  • Set the comboClientID.DataValueField to the property that you want to use as the value for the item (probably the reference....)
  • Call the comboClientID.DataBind method to bind the data to the DropDownList



Like this:
Partial Public Class _Default
    Inherits System.Web.UI.Page

    Private _vpItems As List(Of ValuePair)

    Private Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If IsPostBack = False Then
            PopulateCombo()
        Else
            _vpItems = TryCast(Session("_vpItems"), List(Of ValuePair))
        End If
    End Sub
    Private Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender
        cboClientID.DataSource = _vpItems
        cboClientID.DataTextField = "Description"
        cboClientID.DataValueField = "Value"
        cboClientID.DataBind()
    End Sub
    Public Sub PopulateCombo()
        cboClientID.Items.Clear()

        'Dim cmdDevices As SqlCommand = New SqlCommand("GetDevices", DBConnection.MyConnObj)'
        'cmdDevices.CommandType = CommandType.StoredProcedure;'

        'With cmdDevices'
        '    .Parameters.Add("@ProductID", SqlDbType.VarChar).Value = ""'
        '    .Parameters.Add("@ClientID", SqlDbType.VarChar).Value = "sa"'
        '    .Parameters.Add("@RecordDeleted", SqlDbType.Bit).Value = 0'
        'End With'
        'dtClients.Load(cmdDevices.ExecuteReader())'

        'For Each dr As DataRow In dtClients.Rows'
        '    cboClientID.Items.Add(New ValuePair(dr.Item("Client_ID"), dr.Item("Client_Name")).ToString)'
        'Next'


        _vpItems = New List(Of ValuePair)
        For i As Integer = 1 To 10
            _vpItems.Add(New ValuePair(i, String.Format("{0} {1}", "Description for Item", i.ToString)))
        Next
        Session("_vpItems") = _vpItems
       
    End Sub
End Class


-Frinny

Oh yeah, I wanted to tell you that you should be referring to the MSDN Library for documentation on .NET controls and other programming concepts. It has all the documentation you need to figure out how to use the ASP.NET DropDownList.

This post has been edited by Frinavale: 28 September 2011 - 08:17 PM

Was This Post Helpful? 0
  • +
  • -

#6 Ahleki  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 55
  • Joined: 01-June 10

Re: Value of type ListItem cannot be converted to 'Valuepair'

Posted 29 September 2011 - 01:14 AM

View PostFrinavale, on 28 September 2011 - 11:54 PM, said:

Normally I don't spell out what I was hinting at but today I'm in a strange mood.

So, what I recommended before was to add code that will handle casting the ValuePair type into a ListItem type. To do this you have to implement some code for the CType operator.


This is what your code would look like for the ValuePair class:
Public Class ValuePair

    Public Value As Object
    Public Description As String
    Public Reference As String

 
    Public Sub New(ByVal NewValue As Object, ByVal NewDescription As String, Optional ByVal NewRef As String = "")
        Value = NewValue
        Description = NewDescription
        Reference = NewRef
    End Sub

    Public Property UnderlyingValue() As String
        Get
            Return Value
        End Get
        Set(ByVal Thisvalue As String)
            Value = Thisvalue
        End Set
    End Property

    Public Overrides Function ToString() As String
        Return Description
    End Function
    Public Shared Narrowing Operator CType(ByVal initialData As ListItem) As ValuePair
        Return New ValuePair(initialData.Value, initialData.Text)
    End Operator

    Public Shared Widening Operator CType(ByVal initialData As ValuePair) As ListItem
        Return New ListItem(initialData.Description, initialData.Value)
    End Operator

End Class


I modified your PopulateCombo method to test this out and it works fine:
    Public Sub PopulateCombo()
        cboClientID.Items.Clear()

        'Dim cmdDevices As SqlCommand = New SqlCommand("GetDevices", DBConnection.MyConnObj)'
        'cmdDevices.CommandType = CommandType.StoredProcedure'

        'With cmdDevices'
        '    .Parameters.Add("@ProductID", SqlDbType.VarChar).Value = ""'
        '    .Parameters.Add("@ClientID", SqlDbType.VarChar).Value = "sa"'
        '    .Parameters.Add("@RecordDeleted", SqlDbType.Bit).Value = 0'
        'End With'
        'dtClients.Load(cmdDevices.ExecuteReader())'

        'For Each dr As DataRow In dtClients.Rows'
        '    cboClientID.Items.Add(New ValuePair(dr.Item("Client_ID"), dr.Item("Client_Name")).ToString)'
        'Next'


        For i As Integer = 1 To 10
            cboClientID.Items.Add(New ValuePair(i, String.Format("{0} {1}", "Description for Item", i.ToString)))
        Next
    End Sub


There's another approach that you can take though.
You could convert your Public members into Properties to allow ASP.Net to bind the DropDownList to them. (In my opinion using using Properties is just better programming practice anyways).

Using this approach you would convert the Public members in your ValuePair class into properties like this:
Public Class ValuePair

    'Public Value As Object'
    'Public Description As String'
    'Public Reference As String'

    Private _value As Object
    Private _description As String
    Private _reference As String
    Public Property Value() As Object
        Get
            Return _value
        End Get
        Set(ByVal value As Object)
            _value = value
        End Set
    End Property
    Public Property Description() As String
        Get
            Return _description
        End Get
        Set(ByVal value As String)
            _description = value
        End Set
    End Property
    Public Property Reference() As String
        Get
            Return _reference
        End Get
        Set(ByVal value As String)
            _reference = value
        End Set
    End Property

    Public Sub New(ByVal NewValue As Object, ByVal NewDescription As String, Optional ByVal NewRef As String = "")
        Value = NewValue
        Description = NewDescription
        Reference = NewRef
    End Sub

    Public Property UnderlyingValue() As String
        Get
            Return Value
        End Get
        Set(ByVal Thisvalue As String)
            Value = Thisvalue
        End Set
    End Property

    Public Overrides Function ToString() As String
        Return Description
    End Function
End Class



Then in your PopulateCombo method you would:
  • Create a list of ValuePair objects based on the information retrieved from the database
  • Set the comboClientID.DataSource to this list
  • Set the comboClientID.DataTextField to the property that you want displayed as text (probably the "Description" property)
  • Set the comboClientID.DataValueField to the property that you want to use as the value for the item (probably the reference....)
  • Call the comboClientID.DataBind method to bind the data to the DropDownList



Like this:
Partial Public Class _Default
    Inherits System.Web.UI.Page

    Private _vpItems As List(Of ValuePair)

    Private Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If IsPostBack = False Then
            PopulateCombo()
        Else
            _vpItems = TryCast(Session("_vpItems"), List(Of ValuePair))
        End If
    End Sub
    Private Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender
        cboClientID.DataSource = _vpItems
        cboClientID.DataTextField = "Description"
        cboClientID.DataValueField = "Value"
        cboClientID.DataBind()
    End Sub
    Public Sub PopulateCombo()
        cboClientID.Items.Clear()

        'Dim cmdDevices As SqlCommand = New SqlCommand("GetDevices", DBConnection.MyConnObj)'
        'cmdDevices.CommandType = CommandType.StoredProcedure;'

        'With cmdDevices'
        '    .Parameters.Add("@ProductID", SqlDbType.VarChar).Value = ""'
        '    .Parameters.Add("@ClientID", SqlDbType.VarChar).Value = "sa"'
        '    .Parameters.Add("@RecordDeleted", SqlDbType.Bit).Value = 0'
        'End With'
        'dtClients.Load(cmdDevices.ExecuteReader())'

        'For Each dr As DataRow In dtClients.Rows'
        '    cboClientID.Items.Add(New ValuePair(dr.Item("Client_ID"), dr.Item("Client_Name")).ToString)'
        'Next'


        _vpItems = New List(Of ValuePair)
        For i As Integer = 1 To 10
            _vpItems.Add(New ValuePair(i, String.Format("{0} {1}", "Description for Item", i.ToString)))
        Next
        Session("_vpItems") = _vpItems
       
    End Sub
End Class


-Frinny

Oh yeah, I wanted to tell you that you should be referring to the MSDN Library for documentation on .NET controls and other programming concepts. It has all the documentation you need to figure out how to use the ASP.NET DropDownList.


Thanks for the help but the problem still lies under the SelectedIndexChanged event of the combo box as I had stated earlier.
i tried using third party controls but I figured that as you stated ASP.NET controls do not support GDI.
Was This Post Helpful? 0
  • +
  • -

#7 Frinavale  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 205
  • View blog
  • Posts: 776
  • Joined: 03-June 10

Re: Value of type ListItem cannot be converted to 'Valuepair'

Posted 29 September 2011 - 06:25 AM

Did you try the CType methods?

The thing is that you can't store the whole object in the ListItem...
You're going to have to store something that identifies the object (in the value) so that you can retrieve it again.

-Frinny
Was This Post Helpful? 0
  • +
  • -

#8 Ahleki  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 55
  • Joined: 01-June 10

Re: Value of type ListItem cannot be converted to 'Valuepair'

Posted 30 September 2011 - 02:20 AM

View PostFrinavale, on 29 September 2011 - 04:25 PM, said:

Did you try the CType methods?

The thing is that you can't store the whole object in the ListItem...
You're going to have to store something that identifies the object (in the value) so that you can retrieve it again.

-Frinny

Hey thanks for everything you are a wizard. Is there a way I can hide the ID part of the listitems in the combo box. I have tried out some weird stuff but nothing seems to be working.
Was This Post Helpful? 0
  • +
  • -

#9 Frinavale  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 205
  • View blog
  • Posts: 776
  • Joined: 03-June 10

Re: Value of type ListItem cannot be converted to 'Valuepair'

Posted 30 September 2011 - 06:58 AM

Set the Value Property of the ListItem to the ID.

Set the Text Property of the ListItem to the "Description" (Or whatever you want to display in the DropDownList).

When the SelectedIndexChanged event occurs, retrieve the SelectedValue to get the ID.

-Frinny
Was This Post Helpful? 0
  • +
  • -

#10 Ahleki  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 55
  • Joined: 01-June 10

Re: Value of type ListItem cannot be converted to 'Valuepair'

Posted 03 October 2011 - 12:49 AM

View PostFrinavale, on 30 September 2011 - 04:58 PM, said:

Set the Value Property of the ListItem to the ID.

Set the Text Property of the ListItem to the "Description" (Or whatever you want to display in the DropDownList).

When the SelectedIndexChanged event occurs, retrieve the SelectedValue to get the ID.

-Frinny


Ok thanks for everything I appreciate it
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1