Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF Getting Control null reference during InitializeComponent

Tags:

c#

wpf

So my InitializeComponent method call in the Window's constructor is running through the XML and adding the controls and plugging them into their events.

So when a property of one of the controls changes it calls the Method that subscribes to the event. The method references a control that has not yet been built.

Why does this happen in this order here? It worked in WinForms because the events were not fired until later, after all the controls were created. Is there a way to force this in WPF?

The other solutions I see are

  • I need to subscribe to the events after initialization.

  • I need to check for null whenever I deal with a control.

like image 942
rediVider Avatar asked Mar 25 '10 18:03

rediVider


3 Answers

I just had this issue too, and solved it by wrapping the line accessing the null control in a null check. This seems like a bit of a hack workaround.

I think WPF is trying to be helpful here by calling our Checked event during InitializeComponent(), in an effort to ensure that any UI logic (e.g. showing/hiding related components) is executed based on the initial state of the checkbox. I tested having the Checkbox unchecked by default, and the event handler is not called, even though I have it wired to both the Checked and Unchecked events. I even reproduced this in a blank WPF project with a single Checkbox on the screen, and it behaves the same.

The problem with this default behavior is obviously that some of the other components are not yet initialized. I think WPF should wait until all the components are initialized before firing the Checked event by default. This might not be considered a bug, but I'm gonna add a note to the relevant MSDN page anyway...

like image 60
Jordan Rieger Avatar answered Oct 13 '22 22:10

Jordan Rieger


You should be able to check the IsInitialized or IsLoaded properties on your Window to verify it has finished initializing/loading. Otherwise, you would need to check for null or add your event subscriptions in your code behind (after InitializeComponent).

Also, you may be able to adjust how you access the elements. For example, if you have something like:

<ListBox x:Name="listBox" SelectionChanged="OnListBoxSelectionChanged" />

Then in your code behind you can get the list box several ways:

private void OnListBoxSelectionChanged(object sender, SelectionChangedEventArgs e) {
    ListBox lb = this.listBox; // May be null
    ListBox lb = sender as ListBox; // Should never be null
    ListBox lb = e.Source as ListBox; // Same as sender in this case
    ListBox lb = e.OriginalSource as ListBox; // Always the element that started the event (if handler is not attached directly to ListBox).
    // ... Do Something ...
}
like image 32
CodeNaked Avatar answered Oct 13 '22 23:10

CodeNaked


It was the Checked event on a radiobutton. When i removed Checked="true" from the xaml the issue went away. (though it is checked when the Window starts). Not sure what's going on here, but at least I didn't have to change anything major to fix it... yet.

like image 40
rediVider Avatar answered Oct 13 '22 22:10

rediVider