1

I'm trying to show a label based on the selected value of a combo box. I'm using VS2010.

Here's the code:

private void pointsSettings_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (this.pointsSettings.SelectedValue.ToString() == "between")
        {
           pointsAboveLabel.Visibility = Visibility.Collapsed;
        }
        else
        {
           pointsAboveLabel.Visibility = Visibility.Visible;
        }
    }

And the XAML:

 <ComboBox Name="pointsSettings" SelectionChanged="pointsSettings_SelectionChanged">
     <ComboBoxItem Content="between" />
     <ComboBoxItem Content="above" IsSelected="True" />
     <ComboBoxItem Content="below" />
 </ComboBox>
 <Label Content="points" Name="pointsAboveLabel" />
 <Label Content="and" Name="pointsBetweenLabel" Visibility="Collapsed" />

And here is the error I got: enter image description here Text reads: "Object reference not set to an instance of an object".

I'm aware that there is another question very similar this - with the same error in fact- however the solution provided (moving a variable initialization to above the InitializeComponent() method call) is not appropriate for me as I have no object initialization.

Any and all help is appreciated most warmly.

Bolu
  • 8,696
  • 4
  • 38
  • 70
Luke Ashford
  • 50
  • 1
  • 4
  • 1
    Almost all cases of `NullReferenceException` are the same. Please see "[What is a NullReferenceException in .NET?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-in-net)" for some hints. – John Saunders Feb 26 '13 at 17:10
  • @JohnSaunders Thanks for that. I really should start to debug independently, and then ask only if I need the help. Although in this instance I would probably still have asked, as I had assumed that the the event handlers ran after all the XAML had been executed. I will bookmark that link, I feel it may come in handy... – Luke Ashford Feb 26 '13 at 17:40
  • Note that the answer from @BrianS, below, pretty much says what my link said: the variable is not initialized. He answers that the _reason_ it's not initialized is that the UI has not initialized it yet. – John Saunders Feb 26 '13 at 17:58

1 Answers1

6

This happens because the pointsSettings_SelectionChanged happens before the UI is fully initialized (you can see in the callstack that it comes from the InitializeComponents() call). So the label has not been initialized in the UI, and therefore your variable in the codebehind pointing to that label is null. So it is effectively the same problem as the other question, however it is the WPF framework that is initializing the variable, not you.

Your XAML is evaluated sequentially, so it hits the ComboBox and initializes it (including the initially selected value) and triggers the SelectionChanged event before the label has been initialized. You'll notice if you change the order of your XAML so that the Label is above the ComboBox, you won't have the problem because the Label will be initialized before the event is fired.

To solve this, I would suggest adding a condition to the pointsSettings_SelectionChanged method to return if the pointsAboveLabel is null:

private void pointsSettings_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if(pointsAboveLabel == null) return;
    //rest of code
}

And since you are hard-coding the initially selected value in the ComboBox, you can hard-code the initial Visibility of the Label.

But you've got another problem in your code - the SelectedValue of the ComboBox will never be a string as you've got it setup now. The SelectedValue will be a ComboBoxItem. In order to see the string value you're putting in the ComboBoxItem, you'll need to look at the Content property. So you'll need something like this:

ComboBoxItem item = pointsSettings.SelectedValue as ComboBoxItem;
if(item.Content.ToString() == "between")
{
  ...
}
Brian S
  • 5,675
  • 1
  • 22
  • 22
  • Thank you ever so much, your solution worked perfectly. One quick question, in the XAML should I also put the other label (hidden by default) above the combo box as well, or do I only need to have the visible-by-default label defined before the combo box? – Luke Ashford Feb 26 '13 at 17:33
  • I added that information mostly to demonstrate _why_ this is happening. So my suggestion is to place the label wherever it should be from a User Experience perspective (above or below, whichever delivers the right experience to the user) and then adjust the Code Behind to handle that scenario. I'm glad this worked for you - another suggestion is that you may want to look into MVVM. There's a small learning curve, but it is really the standard approach for building WPF apps, and makes life much easier in the long term. – Brian S Feb 26 '13 at 17:39
  • I'll look into it, once I've finished learning the basics of WPF. Thanks again. – Luke Ashford Feb 26 '13 at 17:48