0

in my VS 2022 Community Edition, WindowsForms Project: I have a combobox with a SelectedValueChange Event and still getting an error:

System.NullReferenceException: Object not set to an instance of an object.

The code:

private void cmbChooseTask_SelectedValueChanged(object sender, EventArgs e)
{
    if (cmbChooseTask.SelectedValue.ToString() == "Install non clusterd instance")
    {
        Form frm = new NonClusterdInstallation();
        frm.Show();
    }

}

The combobox initialization is:

            cmbChooseTask.DataSource = new BindingSource(Dictionaries.DictTypeOfTask, null);
        cmbChooseTask.DisplayMember = "Value";
        cmbChooseTask.ValueMember = "Value";
        cmbChooseTask.SelectedItem = null;

and dictionary definition is:

        public static SortedDictionary<int, string> DictTypeOfTask = new SortedDictionary<int, string>()
    {
        { 1,"Install non clusterd instance" },
        { 2,"Install clusterd instance"},
        { 3, "Set up pre-installed cluster instance" },
        { 4, "Migration" },
        { 5, "Change Collation" },
        { 6, "Add instance to cluster" },
        { 7, "Display all" }
    };
Purclot
  • 483
  • 7
  • 22
  • Does this answer your question? [What is a NullReferenceException, and how do I fix it?](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) –  Apr 24 '22 at 08:59
  • 1
    You should be setting the `DataSource` last when binding. When you set the `DataSource`, that will cause the `SelectedValueChanged` event to be raised, but you haven't set the `DisplayMember` or `ValueMember` yet. Set those first and then the answer I provided below will work as expected. ALWAYS set the `DataSource` last. – user18387401 Apr 24 '22 at 09:01
  • 1
    By the way, why would you set the `ValueMember` to `"Value"`? It seems like `"Key"` would be the logical option, i.e. the control displays the text but exposes the number in code. That way, you can just do a `switch` on `SelectedValue` and test for the valid numbers. What else are the numbers for? – user18387401 Apr 24 '22 at 09:03
  • I would also question why you need a `Dictionary` at all. Could you not just use a `string` array and use the indexes to identify the items like you might be currently using the numeric keys? – user18387401 Apr 24 '22 at 09:05

2 Answers2

2

Quick solution to NRE would be:

if (String.Equals(cmbChooseTask.SelectedValue?.ToString(), "Install non 
clusterd instance"))

or just

if (cmbChooseTask.SelectedValue?.ToString() == "Install non 
clusterd instance")
1

Why call ToString if it's already a string? Just cast it as type string, which will succeed for null too:

if ((string)cmbChooseTask.SelectedValue == "Install non clusterd instance")

Also, based on the text you're comparing it to, I'm guessing that you actually care about the text displayed in the control, which is exposed via the Text property, which is already type string:

if (cmbChooseTask.Text == "Install non clusterd instance")
user18387401
  • 2,514
  • 1
  • 3
  • 8
  • 1
    unfortunately not: the error now is: System.InvalidCastException: Unable to cast object of type System.Collections.Generic.KeyValuePair 2 [System.Int32., System.String] to type System.String. I'm adding the combobox.Source in the question above. – Purclot Apr 24 '22 at 08:54
  • @Purclot, it sounds like you're trying to bind a generic `Dictionary` to your `ComboBox` but you're doing it wrong. If the `SelectedValue` is a `KeyValuePair` then calling `ToString` on it may not throw and exception but it can never produce the actual data you're looking for. Please edit your question and show us EXACTLY how you're populating the `ComboBox` and the `Dictionary` you're binding to it. – user18387401 Apr 24 '22 at 08:58
  • thank you. I've placed the combobox binding code above in the question. – Purclot Apr 24 '22 at 09:00