2
votes

Pretty specific and weird problem here, Google and the rest couldn't give me an answer.

I have a form with two ComboBoxes, we'll say A and B. Selecting an item in A pulls some info from a database, puts it in Dictionary, and uses BindingSource to put it in B. When the user selects something from B, return values are set and nothing else.

The problem is with ComboBox B. In its SelectedIndexChanged handler, attempting to unbox its SelectedItem causes the ComboBox to 'freeze' so it no longer displays the result of new selections from ListBox B and long lists do not refresh when scrolled up/down. The ComboBox still functions, though, if you remember where the data is

The SelectedIndexChanged Handler of B:

private void comboBox2_SelectedIndexChanged_1(object sender, EventArgs e)
{
    if (dataSourceSelect)
        return;
    else
    {
        ComboBox comboBox = (ComboBox)sender;

        var dummy = comboBox2.SelectedItem;
        // System.Collections.Generic.KeyValuePair<int, string> dummy2 =
        //     (System.Collections.Generic.KeyValuePair<int, string>)dummy;
    }
}

There are two dummy variables to show that it isn't the SelectedItem property causing the problem, only the unboxing.

Using this exact code lets ComboBox work correctly, but it's unable to return data. Enabling the commented-out line lets it return values, but stops it from refreshing.

There are two things this code won't show:

  1. Even if you put the commented line in, everything works fine until you do a second selection from ComboBox A. Put another way, if you select from ComboBox A once, ComboBox B will refresh based on your input. But if the selection from A is changed, B freezes the last value shown, and long lists no longer update when scrolled.

  2. The code that fills ComboBox A and B are nearly identical, as are their click handlers, yet A works without any problem all the time, and B freezes when you do a second selection from A.

I can only theorize as to the cause of this, but my guess is that unboxing uses some temp memory location that hates to be touched twice. There might also be some problem with the code that populates B based on A's selection, but the fact that it works fine when unboxing is commented out reduces that suspicion.

From what I can tell, I need to do one of the following:

  1. Access SelectedItem in another fashion
  2. Access the data in SelectedItem without unboxing
  3. Find a method that avoids unboxing altogether

Apologies for the formatting, StackOverflow seems to be ignoring my attempts to make it more readable

1
What is the type returned by SelectedItem.GetType()? Are you sure that the cast is not throwing an exception?Thomas Levesque
Two interesting things showed up from your questions. Its type is "KeyValuePair`2", which I have not researched as yet, and do not know if it is significantly different from KeyValuePair. And in hindsight, checking for an exception is the obvious thing to do, because it throws a null reference exception on the second selection from A. I will check the code between them, I believe I set something to null/0 to prevent a different issueRuud A.
KeyValuePair``2 just means that KeyValuePair is a generic type with 2 type parameters; usually the type arguments are specified between square brackets. Anyway, yes, it's possible that the SelectedItem is null at some point, so you need to check whether it's null before you cast. Trying to unbox a null value will always fail.Thomas Levesque
Learning more and more about C# with this project. Since I assign a new dictionary filled with different information into ComboBox B, I first set its DataSource to null. This fired the SelectedIndexChanged event, which attempted to access the SelectedItem of a null list, causing the error and the freezing. Thank you very much for suggesting the exception, this had been plagueing me for daysRuud A.

1 Answers

0
votes

A very big thank you to Thomas Levesque ( https://stackoverflow.com/users/98713/thomas-levesque ) for suggesting to check for an exception in the comments.

Since I wanted to assign a new dictionary filled with different information into ComboBox B after a new selection in A, I first set its B's DataSource to null (in the SelectedIndexChanged event of A). This fired the SelectedIndexChanged event of B, which attempted to access the SelectedItem of a null list, throwing a NullReferenceError, causing the error and the freezing.

There are two ways this could have been avoided:

  1. Checking to see if B's SelectedItem was null before attempting to unbox the value
  2. Using other code to prevent the SelectedIndexChanged event from accessing B's SelectedItem