Solved

Can't change the datasource of a ComboBox (winforms)

Posted on 2006-07-13
14
819 Views
Last Modified: 2012-06-27
I have a combobox that I've successfully bound (the first time, at least) to a dataset.  When a button is clicked on the form, I grab the dataset, set the .DataSource, .DisplayMember and .ValueMember-  When I then make the combobox visible, everything works as advertised.  When a selection is made from the combo, I reset my .DataSource to nothing.  

Here's the problem-  The second time the user clicks the button to bring up the same combo, I confirmed that the dataset is successfully created, but the combobox is empty, it's datasource is "Nothing", and will not allow it's .DataSource property to be set to anything but "Nothing" (I've stepped the code, and tried to enter the .DataSet property while debugging, but it snaps back to "Nothing".)

Here's a snippet of the code; it's pretty straight-forward:

        Private Sub addpersonButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles addpersonButton.Click
            Dim dsEmployees As DataSet

                addpersonButton.Visible = False

                comboDataLoading = True

                dsEmployees = employees.GetAllEmpNames()

                addpersonComboBox.DataSource = dsEmployees.Tables(0)
                addpersonComboBox.DisplayMember = "FullName"
                addpersonComboBox.ValueMember = "EmpID"

                addpersonComboBox.Visible = True

                comboDataLoading = False
        End Sub


        Private Sub addpersonComboBox_SelectedValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles addpersonComboBox.SelectedValueChanged
            If comboDataLoading = True Then
                Exit Sub
            End If

            addpersonComboBox.Visible = False

            comboDataLoading = True

            addpersonComboBox.DataSource = Nothing
            addpersonComboBox.DisplayMember = ""
            addpersonComboBox.ValueMember = ""
            addpersonComboBox.DataBindings.Clear()
            addpersonComboBox.Items.Clear()

            comboDataLoading = False

            addpersonButton.Visible = True
        End Sub


...That's it.  When the addpersonButton is clicked a second time, I can see in the debugger that the .DisplayMember and .ValueMember properties are set properly, but nothing I do will cause the combo's .DataSource property to be set to the dsEmployees dataset table.

Is this a bug in .Net?  You can see that I've tried clearing anything that could possibly have anything to do with databindings in the second procedure, but it doesn't change the behavior of this screwy thing.

Thanks in Advance for any help.
0
Comment
Question by:ccoton
14 Comments
 
LVL 6

Expert Comment

by:carmodyk
ID: 17102750
Hmmm...Maybe a quick fix.  Try this:  instead of,  Dim dsEmployees As DataSet  Declare it as this Dim dsEmployees As new DataSet
0
 
LVL 5

Expert Comment

by:proten
ID: 17102963
You are setting your addpersonComboBox.Visible = False but are never resetting it to true.  
Try adding addpersonComboBox.Visible = True in your click event.
0
 
LVL 5

Expert Comment

by:proten
ID: 17102967
Sorry misread
ignore my post
0
 
LVL 5

Expert Comment

by:proten
ID: 17102976
Sorry for posting so many times.

Try setting the addpersonComboBox.Visible = True before you set the datasource.
0
 

Author Comment

by:ccoton
ID: 17103478
Thanks for the replies.

Sorry about the confusion-  I have played with so many versions of the two procedures above that I didn't include the "addpersonComboBox.Visible = True" statement in the example.  In the original code, I do set the .Visible property of the combo to True.   Also, I have tried a version of the code with "Dim dsEmployees As New DataSet", with no change in the ComboBox behavior.

I did find a similar post while searching here-  Someone had a similar problem, but thought it was because he had his combo in a Tab Page.  I have mine in a Tab Page as well, but I moved it onto the parent form, with no change in behavior.  The solution he accepted was to iterate through the dataset and load the combo manually.  I may have to do this, but I really would like to know why the combo is behaving this way-  I hate to kludge things with work-arounds when the syntax is straight-forward and should work.
0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 

Author Comment

by:ccoton
ID: 17103549
proten-

Here's someting strange:  When I set the addpersonComboBox.Visible = True before setting the datasource, the combo came up empty the -first- time I brought it up.   Weird.
0
 
LVL 5

Expert Comment

by:proten
ID: 17103612
So correct me if I am wrong:

You have a combobox on a windows form (not in a datagrid or anything like that)
and you are setting the datasource AFTER the combobox is visible?

Are you sure that you are passing back a datatable in the dataset and that the dataset is not empty?
0
 

Author Comment

by:ccoton
ID: 17103801
No, the code as it stands now sets the combo's datasource, etc. BEFORE it's visible, when the user clicks a button.

I then set .Visible to True, and it works.

When the user selects something from the list, I use code in the combo's .SelectedValueChanged event to set the .DataSource to nothing, and to make the combo invisible.

When the user clicks the same button again, the same code is executed, a good dataset is generated once again, I set the datasource, etc. once again, but the combo is empty.  I double-checked the dataset at this point, and have good data in it, just like the first time.

Checking property values in the debugger shows that the combo's .Datasource property is now "Nothing" in this second go-around; even when I try to manually set this value back to the dataset, it snaps back to "Nothing".
0
 

Author Comment

by:ccoton
ID: 17103829
To add the post above:  The combo box is in a groupbox that sits on a tab page.

I moved the combo out onto the form; it exhibits the same behavior.
0
 
LVL 34

Accepted Solution

by:
Sancler earned 500 total points
ID: 17104654
I can't reproduce the behaviour.  Try this.  One form.  One button.  One combobox (called cb1).

    Dim loading As Boolean = True

    Private Sub FormTest_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim ds As New DataSet
        ds.Tables.Add(maketable(2))
        cb1.DataSource = ds.Tables(0)
        cb1.DisplayMember = "Description"
        cb1.ValueMember = "Value"
        cb1.Visible = True
        loading = False
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim ds As New DataSet
        Static rownumbers As Integer = 2
        rownumbers += 1
        loading = True
        ds.Tables.Clear()
        ds.Tables.Add(maketable(rownumbers))
        cb1.DataSource = ds.Tables(0)
        cb1.DisplayMember = "Description"
        cb1.ValueMember = "Value"
        loading = False
        cb1.Visible = True
    End Sub

    Private Sub cb1_SelectedValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles cb1.SelectedValueChanged
        If loading Then Exit Sub
        cb1.Visible = False
        loading = True
        cb1.DataSource = Nothing
        loading = False
    End Sub

    Private Function maketable(ByVal rows As Integer) As DataTable
        Dim dt As New DataTable
        Dim dc As New DataColumn
        With dc
            .ColumnName = "Description"
            .DataType = GetType(String)
        End With
        dt.Columns.Add(dc)
        Dim dc1 As New DataColumn
        With dc1
            .ColumnName = "Value"
            .DataType = GetType(Integer)
        End With
        dt.Columns.Add(dc1)
        For i As Integer = 1 To rows
            Dim dr As DataRow = dt.NewRow
            dr(0) = "Item" & i.ToString
            dr(1) = i
            dt.Rows.Add(dr)
        Next
        Return dt
    End Function

It seems to me, with one exception, to reproduce the essential elements of your code.  The exception is that the dataset is declared as New.  Without that, the code breaks with a "Object not set to instance ..." error.  

Most of the code - the maketable function - just produces a dummy table and data just for testing purposes.  It is a new table every time.  The form load produces such a table, puts it in a dataset, and binds the combobox to it.  The cb's sub breaks the binding.  The button makes a new dataset, remakes the (new) table, adds it to the dataset, and remakes the binding.  The fact that it is a new table is indicated by the increased number of rows in it.

Can I suggest that you first examine the code and see whether, in its essentials relating to the combobox, it looks different from yours.  It looks the same to me.  Unless you do identify an essential difference, then try this code.  It works OK for me.  If it works OK for you, we can then start to look for those detailed differences between this code and your existing code which start producing the symptom you describe.

Roger
0
 

Author Comment

by:ccoton
ID: 17104812
Roger-

Thanks, I'll give it a try tomorrow.  I'm about to go blind right now.  After searching the web for hours, I've run across other people that have had the same problem, as well as other PITA problems surrounding binding ComboBoxes.  Each of them, to a person, finally gave up and did everything manually.   I still intend to get to the bottom of this here, but until then, I used the following code to do it manually (using the same dataset from my first post):

________________
Loading:
            For Each dsRow In dsEmployees.Tables(0).Rows
                addpersonComboBox.Items.Add(New ListItem(dsRow.Item("EmpID").ToString(), dsRow.Item("FullName").ToString()))
            Next

Retrieving text and key:
            Dim selectedListItem As ListItem = DirectCast(addpersonComboBox.SelectedItem, ListItem)
            MessageBox.Show(selectedListItem.ID + ", " + selectedListItem.Name)

My ListItem class:

Public Class ListItem
    Private mID As String
    Private mName As String

    Public Sub New(ByVal ID As String, ByVal Name As String)
        mID = ID
        mName = Name
    End Sub

    Public Sub New()
        'Empty default constructor
    End Sub

    Public Property ID() As String
        Get
            Return mID
        End Get
        Set(ByVal Value As String)
            mID = Value
        End Set
    End Property

    Public Property Name() As String
        Get
            Return mName
        End Get
        Set(ByVal Value As String)
            mName = Value
        End Set
    End Property

    Public Overrides Function ToString() As String
        Return mName
    End Function
End Class
________________

0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

This tutorial demonstrates one way to create an application that runs without any Forms but still has a GUI presence via an Icon in the System Tray. The magic lies in Inheriting from the ApplicationContext Class and passing that to Application.Ru…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

746 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now