?
Solved

Combobox SelectedIndex Value not Changing

Posted on 2011-04-26
27
Medium Priority
?
1,283 Views
Last Modified: 2012-05-11
I am filling a combo box at runtime with a dataset populated from a query to a sql server and set my properties as detailed below in the code snipet.  I want to use the SelectedIndex value to determine if the user has actually made a selection or not.

It's strange.  When I click in the dropdown arrow, press a letter to navigate, and then tab to select an entry in the list; ...when referrencing the SelectedIndex value it remains -1.

How can I get the index to change when the value is changed in the manner described above?  If clicking an item in the list with the mouse however it does change.
With cboInventoryItemSelection
                .DataSource = ds.Tables("inventory")
                .DisplayMember = "inventory_item"
                .SelectedItem = Nothing
            End With

Open in new window

0
Comment
Question by:vbNewbie2009
  • 9
  • 5
  • 4
  • +4
24 Comments
 
LVL 42

Expert Comment

by:dqmq
ID: 35472728
In what event are you trying to detect the selection?
0
 
LVL 1

Author Comment

by:vbNewbie2009
ID: 35472740
I actually wasn't using an event, but was referencing when the user presses a button to add an inventory item to a list.  If a value isn't selected I don't want to proceed.  If i throw a msgbox onto the selectedIndex value it always returns a -1 if I use the dropdown arrow and tab to a value.

If cboQuestion.SelectedIndex <> -1 Then...
0
 
LVL 10

Expert Comment

by:Asim Nazir
ID: 35473063
Have you checked SelectedValue property? Does this change?
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
LVL 1

Author Comment

by:vbNewbie2009
ID: 35476183
asimnazir123:  I just checked; the SelectedValue property actually Is Nothing...it doesn't change reflect that i have a value even though I see the value I tabbed to select on the screen.
0
 
LVL 1

Author Comment

by:vbNewbie2009
ID: 35481397
Here's an actual example of what I'm having problems with; code attaced.  Just replace a generic windows form with this class and on load it will create the ComboBox and Button.  

When you click the drop down arrow, press the "o" character inventory item, then press "TAB" to select the item; upon pressing the button the SelectedIndex is actually -1.

If you then click the drop down arrow and click the "o" character inventory item, then clicking the button reflects the proper index of 14.

I want the user to be able to simply press a letter and TAB to select; but upon validating other parameters I need the SelectedIndex to reflect 14 and not -1.  How can I accomplish this?
Public Class Form1

    Private m_Controls As New Hashtable()

    Public Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim ds As New DataSet
        Dim dt As DataTable
        Dim dr As DataRow
        Dim idCoulumn As DataColumn
        Dim nameCoulumn As DataColumn
        Dim i, j As Integer

        dt = New DataTable()
        idCoulumn = New DataColumn("ID", Type.GetType("System.Int32"))
        nameCoulumn = New DataColumn("InventoryItem", Type.GetType("System.String"))

        dt.Columns.Add(idCoulumn)
        dt.Columns.Add(nameCoulumn)

        For i = 97 To 150
            dr = dt.NewRow()
            dr("ID") = i
            dr("InventoryItem") = Chr(i).ToString + " -InventoryItem"
            dt.Rows.Add(dr)
        Next i
        ds.Tables.Add(dt)
        ds.Tables.Item(0).TableName = "Table"

        'For j = 0 To ds.Tables("Table").Rows.Count - 1
        '    MsgBox(ds.Tables("Table").Rows(j).Item(0) & "   --   " & ds.Tables("Table").Rows(j).Item(1))
        'Next j

        Dim cbo = New ComboBox()
        Me.Controls.Add(cbo)
        With cbo
            .Name = "ComboBox1"
            .Location = New Point(30, 50)
            .Width = 150
            .DisplayMember = "InventoryItem"
            .ValueMember = "ID"
            .DataSource = ds.Tables("Table")
            .SelectedItem = Nothing
        End With
        m_Controls.Add(cbo.Name, cbo)

        Dim btn = New Button()
        Me.Controls.Add(btn)
        With btn
            .Name = "Button1"
            .Text = "SelectedIndex Check"
            .Location = New Point(30, 75)
            .Width = 150
        End With
        AddHandler btn.Click, AddressOf SelectedIndexCheck

    End Sub

    Private Sub SelectedIndexCheck(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim cbo As ComboBox = DirectCast(m_Controls.Item("ComboBox1"), ComboBox)
        MsgBox(cbo.SelectedIndex)
    End Sub
End Class

Open in new window

0
 
LVL 48

Expert Comment

by:Mikal613
ID: 35487773
Is this a Web Project? If yes then you need AutoPostback = true
0
 
LVL 1

Author Comment

by:vbNewbie2009
ID: 35487881
No this isn't a Web Project, it is a Windows Forms Application
0
 
LVL 48

Expert Comment

by:Mikal613
ID: 35487966
You are adding the handler to the click of the button and not the combobox
0
 
LVL 48

Expert Comment

by:Mikal613
ID: 35487977
Public Class Form1
    Private m_Controls As New Hashtable()

    Public Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim ds As New DataSet
        Dim dt As DataTable
        Dim dr As DataRow
        Dim idCoulumn As DataColumn
        Dim nameCoulumn As DataColumn
        Dim i, j As Integer

        dt = New DataTable()
        idCoulumn = New DataColumn("ID", Type.GetType("System.Int32"))
        nameCoulumn = New DataColumn("InventoryItem", Type.GetType("System.String"))

        dt.Columns.Add(idCoulumn)
        dt.Columns.Add(nameCoulumn)

        For i = 97 To 150
            dr = dt.NewRow()
            dr("ID") = i
            dr("InventoryItem") = Chr(i).ToString + " -InventoryItem"
            dt.Rows.Add(dr)
        Next i
        ds.Tables.Add(dt)
        ds.Tables.Item(0).TableName = "Table"

        'For j = 0 To ds.Tables("Table").Rows.Count - 1
        '    MsgBox(ds.Tables("Table").Rows(j).Item(0) & "   --   " & ds.Tables("Table").Rows(j).Item(1))
        'Next j

        Dim cbo = New ComboBox()
        Me.Controls.Add(cbo)
        With cbo
            .Name = "ComboBox1"
            .Location = New Point(30, 50)
            .Width = 150
            .DisplayMember = "InventoryItem"
            .ValueMember = "ID"
            .DataSource = ds.Tables("Table")
            .SelectedItem = Nothing
        End With
        AddHandler cbo.SelectedIndexChanged, AddressOf SelectedIndexCheck
        m_Controls.Add(cbo.Name, cbo)

        Dim btn = New Button()
        Me.Controls.Add(btn)
        With btn
            .Name = "Button1"
            .Text = "SelectedIndex Check"
            .Location = New Point(30, 75)
            .Width = 150
        End With


    End Sub

    Private Sub SelectedIndexCheck(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim cbo As ComboBox = DirectCast(m_Controls.Item("ComboBox1"), ComboBox)
        MsgBox(cbo.SelectedIndex)
    End Sub

End Class
0
 
LVL 1

Author Comment

by:vbNewbie2009
ID: 35488077
When using the handler on the selectedIndexChanged event it should display the MsgBox immediately when clicking the drop down arrow, typing a letter such as "o", and then tabbing to select, but it doesn't.  The only time the message box is displayed is if you actually click a selection in the drop down.
0
 
LVL 48

Expert Comment

by:Mikal613
ID: 35488516
If you have the message box, you will never be able to change the index unless you set the index via code.


Public Class Form1


    Private m_Controls As New Hashtable()

    Public Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim ds As New DataSet
        Dim dt As DataTable
        Dim dr As DataRow
        Dim idCoulumn As DataColumn
        Dim nameCoulumn As DataColumn
        Dim i, j As Integer

        dt = New DataTable()
        idCoulumn = New DataColumn("ID", Type.GetType("System.Int32"))
        nameCoulumn = New DataColumn("InventoryItem", Type.GetType("System.String"))

        dt.Columns.Add(idCoulumn)
        dt.Columns.Add(nameCoulumn)

        For i = 97 To 150
            dr = dt.NewRow()
            dr("ID") = i
            dr("InventoryItem") = Chr(i).ToString + " -InventoryItem"
            dt.Rows.Add(dr)
        Next i
        ds.Tables.Add(dt)
        ds.Tables.Item(0).TableName = "Table"

        'For j = 0 To ds.Tables("Table").Rows.Count - 1
        '    MsgBox(ds.Tables("Table").Rows(j).Item(0) & "   --   " & ds.Tables("Table").Rows(j).Item(1))
        'Next j

        Dim cbo = New ComboBox()
        Me.Controls.Add(cbo)
        With cbo
            .Name = "ComboBox1"
            .Location = New Point(30, 50)
            .Width = 150
            .DisplayMember = "InventoryItem"
            .ValueMember = "ID"
            .DataSource = ds.Tables("Table")
            .SelectedItem = Nothing
        End With
        AddHandler cbo.Click, AddressOf SelectedIndexClick
        m_Controls.Add(cbo.Name, cbo)

        Dim btn = New Button()
        Me.Controls.Add(btn)
        With btn
            .Name = "Button1"
            .Text = "SelectedIndex Check"
            .Location = New Point(30, 75)
            .Width = 150
        End With
        AddHandler btn.Click, AddressOf SelectedIndexCheck

    End Sub

    Private Sub SelectedIndexCheck(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim cbo As ComboBox = DirectCast(m_Controls.Item("ComboBox1"), ComboBox)
        MsgBox(cbo.SelectedIndex)
    End Sub
    Private Sub SelectedIndexClick(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim cbo As ComboBox = DirectCast(m_Controls.Item("ComboBox1"), ComboBox)
        MsgBox(cbo.SelectedIndex)
    End Sub
End Class
0
 
LVL 83

Expert Comment

by:CodeCruiser
ID: 35490878
I think this is a fact that combobox only changes the selected index when clicked with mouse. Try pressing enter after selecting it with keys.
0
 
LVL 13

Expert Comment

by:Chris Raisin
ID: 35491356
When you have selected the item in the combobox by pressing Tab (which makes the combobox Lose Focus) you must change the Combo Box's "ListIndex" manually to comboBox's TopIndex. (A quirk that goes with the TAB key)

e.g.
Private sub  cbo_LostFocus()
  cbo.ListIndex = cbo.TopIndex
End Sub    

 
0
 
LVL 13

Expert Comment

by:Chris Raisin
ID: 35491661
Please also note, just in case the user uses a mouse-click in a drop-down box rather than keying ANYTHING (it can happen!) you should include the following code.

Private Sub cbo_Click()
   if cbo.ListIndex > -1 then   'you have to include this condition in case
                                             'the user presses a key for an item and it
                                             'is not found in the combox.
                                             'would not apply is combobox type is
                                             'dropdownlist - butr it doesn't hurt to have it
                                             .anyway
     cbo.TopIndex = cbo.ListIndex
  endif
End Sub

If you don't include this test for comboboxes of type 0 or 1 then the TopIndex stays at 0 (zero). (I found that by accident).
 
0
 
LVL 15

Expert Comment

by:x77
ID: 35491711
When Cbo. DropDownStyle is  DropDown, then  The Cbo.Text is independent from Cbo.SelectedValue.

You can try:

     .DropDownStyle = ComboBoxStyle.DropDownList

Then when you press any letter, the SelectedValue is syncronized.

You can try also the AutoComplete feature.
0
 
LVL 1

Author Comment

by:vbNewbie2009
ID: 35491742
CodeCruiser:  Pressing the enter key after tabbing to select did allow the SelectedIndex value to change.

Craisin: I don't see cbo.ListIndex or cbo.TopIndex at options; this is a windows form combobox control?...do you have to call it differently than just cbo.ListIndex?
0
 
LVL 15

Accepted Solution

by:
x77 earned 2000 total points
ID: 35491800
To Try Autocomplete:

            .AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems
            .AutoCompleteMode = AutoCompleteMode.Append
0
 
LVL 83

Expert Comment

by:CodeCruiser
ID: 35491913
So that should solve your problem?
0
 
LVL 13

Expert Comment

by:Chris Raisin
ID: 35492006
That was just an example code with "cbo" the name of the ComboBox.

Replace "cbo" with the name of your combobox. (Is it ComboBox1??)

Give that a try.  :-)
0
 
LVL 1

Assisted Solution

by:vbNewbie2009
vbNewbie2009 earned 0 total points
ID: 35493015
Craisin:  I believe cbo.listindex isn't available in .net, but is selectedindex.  

CodeCruiser:  pressing the enter key afterwards did select the index but i wanted to prevent the extra character press if possible.  X77's method actually does allow the SelectedIndex to change upon Tabbing

X77:  The AutoComplete method you described worked great!  I updated my code to also include some extra KeyUP events on the arrow keys so it would also work pseudo-like the .DropDownStyle method.  
'Final Revision:

Public Class Form1

    Private m_Controls As New Hashtable()

    Public Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim ds As New DataSet
        Dim dt As DataTable
        Dim dr As DataRow
        Dim idCoulumn As DataColumn
        Dim nameCoulumn As DataColumn
        Dim i, j As Integer

        dt = New DataTable()
        idCoulumn = New DataColumn("ID", Type.GetType("System.Int32"))
        nameCoulumn = New DataColumn("InventoryItem", Type.GetType("System.String"))

        dt.Columns.Add(idCoulumn)
        dt.Columns.Add(nameCoulumn)

        For i = 97 To 150
            dr = dt.NewRow()
            dr("ID") = i
            dr("InventoryItem") = Chr(i).ToString + " -InventoryItem"
            dt.Rows.Add(dr)
        Next i
        For i = 97 To 150
            dr = dt.NewRow()
            dr("ID") = i
            dr("InventoryItem") = Chr(i).ToString + " -SomeOtherItem"
            dt.Rows.Add(dr)
        Next i
        ds.Tables.Add(dt)
        ds.Tables.Item(0).TableName = "Table"

        Dim cbo = New ComboBox()
        Me.Controls.Add(cbo)
        With cbo
            .Name = "ComboBox1"
            .Location = New Point(30, 50)
            .Width = 150
            .DisplayMember = "InventoryItem"
            .ValueMember = "ID"
            .DataSource = ds.Tables("Table")
            .SelectedItem = Nothing
            .AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems
            .AutoCompleteMode = AutoCompleteMode.Append

        End With
        m_Controls.Add(cbo.Name, cbo)
        AddHandler cbo.KeyUp, AddressOf ComboBox1_KeyUP

        Dim btn = New Button()
        Me.Controls.Add(btn)
        With btn
            .Name = "Button1"
            .Text = "SelectedIndex Check"
            .Location = New Point(30, 75)
            .Width = 150
        End With
        AddHandler btn.Click, AddressOf SelectedIndexCheck

    End Sub

    Private Sub SelectedIndexCheck(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim cbo As ComboBox = DirectCast(m_Controls.Item("ComboBox1"), ComboBox)
        MsgBox(cbo.SelectedIndex)
    End Sub

    Private Sub ComboBox1_KeyUP(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs)
        Dim cbo As ComboBox = DirectCast(m_Controls.Item("ComboBox1"), ComboBox)

        If e.KeyValue = 37 And cbo.SelectedIndex = -1 Then
            cbo.SelectedIndex = 0
        ElseIf e.KeyValue = 37 And cbo.SelectedIndex = 0 Then
            Exit Sub
        ElseIf e.KeyValue = 37 Then
            cbo.SelectedIndex = cbo.SelectedIndex - 1
        ElseIf e.KeyValue = 38 And cbo.SelectedIndex > 0 Then
            cbo.SelectedIndex = cbo.SelectedIndex
        ElseIf e.KeyValue = 39 Then
            cbo.SelectedIndex = cbo.SelectedIndex + 1
        ElseIf e.KeyValue = 40 Then
            cbo.SelectedIndex = cbo.SelectedIndex
        End If
    End Sub

End Class

Open in new window

0
 
LVL 13

Expert Comment

by:Chris Raisin
ID: 35494071
Thanks for that, glad it worked out.

The lines:
 ElseIf e.KeyValue = 38 And cbo.SelectedIndex > 0 Then
            cbo.SelectedIndex = cbo.SelectedIndex
and:
 ElseIf e.KeyValue = 40 Then
            cbo.SelectedIndex = cbo.SelectedIndex

are not really required, but I suppose they could be there for documentation purposes!  (better to comment them out, since they just take up processing time)

I was working in VB6 of course, but it put you on the correct path. Well done!
:-)
0
 
LVL 1

Author Comment

by:vbNewbie2009
ID: 35494437
Actually those lines were required;...it was odd, I initially tested without those lines and instead of only incrementing by 1 the SelectedIndex value was incrementing by two!...after adding those lines that do appear to do nothing it actually then only started incrementing by 1 as one would expect.
0
 
LVL 13

Expert Comment

by:Chris Raisin
ID: 35494522
What a wonderfully crazy world we live in!  LOL..... Cheers
0
 
LVL 1

Author Closing Comment

by:vbNewbie2009
ID: 35704550
My apologies everyone, i orignally accidentally selected Craisin's response for awarding points.  The solution was by using autocomplete by x77.
0

Featured Post

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When trying to connect from SSMS v17.x to a SQL Server Integration Services 2016 instance or previous version, you get the error “Connecting to the Integration Services service on the computer failed with the following error: 'The specified service …
Simulator games are perfect for generating sample realistic data streams, especially for learning data analysis. It is even useful for demoing offerings such as Azure stream analytics, PowerBI etc.
Using examples as well as descriptions, and references to Books Online, show the documentation available for date manipulation functions and by using a select few of these functions, show how date based data can be manipulated with these functions.
Via a live example, show how to extract information from SQL Server on Database, Connection and Server properties
Suggested Courses

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question