Reading the Text property of a combobox by reference

I have a panel on my Windows form that contains a number of comboboxes. When a user inputs values to these comboboxes and hits the OK button, I need to retrieve the name, datasource (datatable) and Text contents of each combobox the user has put a value in. Here’s what I’ve got so far:

Dim x As Integer
Dim cbxModel As ComboBox
.
.
.
For x = 0 To Me.Panel1.Controls.Count - 1

If Me.Panel1.Controls.Item(x).GetType.ToString Like "*ComboBox" Then

cbxModel = Me.Panel1.Controls.Item(x)
If cbxModel.SelectedText <> Nothing Then
Me.OdbcDAAccess.SelectCommand.CommandText = AddWhereClause(Me.OdbcDAAccess.SelectCommand.CommandText, _

cbxModel.Name, _
cbxModel.DataSource.ToString, _
cbxModel.Text)
'' Model for AddWhereClause call, using an actual combobox on form
'' Me.OdbcDAAccess.SelectCommand.CommandText = AddWhereClause(Me.OdbcDAAccess.SelectCommand.CommandText, "prodid", Me.cbxProdID.Text)
End If
End If

Next

This instantiates a new copy of the current combobox with everything I need EXCEPT the currently selected/input text from the original combobox, the most crucial parameter in my function call. I have a feeling that's because I'm instantiating, not duplicating, the current combobox. I also suspect there's a simple resolution to this, I'm just missing a keyword of some sort.

After doing a bit of research on this forum, I found a reference to a similar question in "Clear the data in all the Controls in a single Form" (http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=383678&SiteID=1). Based on the example within, I modified my paragraph as follows:

For Each cbxModel As Control In Me.Panel1.Controls

'' Using .NET Framework method (for ALL languages)
If cbxModel.GetType.ToString Like "*ComboBox" Then
If cbxModel.Text <> Nothing And _
cbxModel.Text <> " " Then

'' Create duplicate of the generic control cbxModel
'' as a true ComboBox to use ComboBox properties
Dim cbxModel2 As ComboBox = CType(cbxModel, ComboBox)
Me.OdbcDAAccess.SelectCommand.CommandText = AddWhereClause(Me.OdbcDAAccess.SelectCommand.CommandText, _
cbxModel2.DataSource.ToString, _
cbxModel.Text)
'' Model for AddWhereClause call, using an actual combobox on form
'' Me.OdbcDAAccess.SelectCommand.CommandText = AddWhereClause(Me.OdbcDAAccess.SelectCommand.CommandText, "prodid", Me.cbxProdID.Text)

End If
End If

Next

...but I got the same result. No currently selected/input text was returned.

Any idea how I can get the Text property from a control by referencing it indirectly as I've done above




Answer this question

Reading the Text property of a combobox by reference

  • AdriaanDavel

    How about the following.

    If TypeOf cbxModel Is ComboBox Then

    'Cast to combox box as early as possible and use combo box properties, SelectedText, SelectedItem etc.

    ' Change all combo box objects to reference to 'current' object

    Dim current As ComboBox = CType(cbxModel, ComboBox)

    If current.SelectedText <> Nothing And _

    cbxModel.Text <> " " Then

    '' Create duplicate of the generic control cbxModel

    '' as a true ComboBox to use ComboBox properties

    Dim cbxModel2 As ComboBox = CType(cbxModel, ComboBox)

    Me.OdbcDAAccess.SelectCommand.CommandText = AddWhereClause(Me.OdbcDAAccess.SelectCommand.CommandText, _

    cbxModel2.DataSource.ToString, _

    "Not using Combobox obj and members as above" cbxModel.Text)

    '' Model for AddWhereClause call, using an actual combobox on form

    '' Me.OdbcDAAccess.SelectCommand.CommandText = AddWhereClause(Me.OdbcDAAccess.SelectCommand.CommandText, "prodid", Me.cbxProdID.Text)

    End If

    End If


  • Thelostcircuit

    Sounds like broken databinding to me... There's probably something wrong with the way you've bound your controls and/or data sources...

    The SelectedText property will typically return String.Empty in databound scenarios, but the SelectedValue, SelectedItem, and Text properties should all return the appropriate underlying value.

    For instance, create a simple example: One DataSet with one DataTable. A BindingSource whose DataSource is set to the DataSet and the DataMember is set to the DataTable. Use one ComboBox whose DataSource is the BindingSource, DisplayMember is a Field in the DataTable and ValueMember is a Field in the DataTable. Add three Labels, one for the Text property, one for the SelectedValue, and one for any other field in the DataTable that is not already being used for Display or Value Memebers. Add a Button. Then use code similar to the following:

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    For Each c As Control In Me.Panel1.Controls

    If c.GetType Is GetType(ComboBox) Then

    Dim cbx As ComboBox = CType(c, ComboBox)

    Me.Label1.Text = cbx.Text
    Me.Label2.Text = cbx.SelectedValue

    Dim drv As DataRowView = CType(cbx.SelectedItem, DataRowView)
    Me.Label3.Text = drv.Row.Item("Some Column Name")

    End If

    Next

    End Sub

    You'll find that all three labels display the expected values. You issue must stem from something deeper than what you've shown.



  • Ajaykr

    "Use one ComboBox whose DataSource is the BindingSource..."

    That may be the problem. I'm not using a BindingSource at all. As a throw-back to VS2k3 style, my datasource is the dataset itself for all my comboboxes; no middleman BindingSources live in my code. I've heard that this keeps your resulting executable lighter in weight since databinding is done at execution time rather than predefined in the mix. Still, I've never needed actual data from the controls until now.

    Any comments I've give the BindingSource routine a try in the meantime. Thanks, rkimble!



  • Khookie

    Why not do something similar to the following


    Dim cbx As ComboBox

    For Each c As Control In Me.Panel1.Controls
    If TypeOf (c) Is ComboBox Then
    cbx = c

    If cbx.SelectedText.Length > 0 Then
    Me.OdbcDAAccess.SelectCommand.CommandText = AddWhereClause(Me.OdbcDAAccess.SelectCommand.CommandText, cbx.Name, cbx.DataSource.ToString, cbx.Text)
    '' Model for AddWhereClause call, using an actual combobox on form
    '' Me.OdbcDAAccess.SelectCommand.CommandText = AddWhereClause(Me.OdbcDAAccess.SelectCommand.CommandText, "prodid", Me.cbxProdID.Text)
    End If
    End If
    Next


    This looping construct iterates through the panel1 controls collection and processes only combobox within this collection. Then all you need to do is use the properties of the cbx variable in the IF construct


  • Steven Syfuhs

    Nice try, guys, but I think you're both missing the point here. Everything else, being Name, DataSource, even DataTable if I needed it, casts (or transfers) from the generic Control (NewControl, c) to the specific ComboBox (cbxModel, cbx) except the current state of the value properties SelectedText and Text. In fact, nothing having to do with the value state of the combobox is cast, including SelectedIndex, SelectedItem and SelectedValue.

  • Reading the Text property of a combobox by reference