
February 17, 2009 18:16 by
ColinW
While working on a WPF project last week, I ended up in a situation where I needed a TextBox with a TextBlock below it that needed to keep it’s display synchronized with whatever was in the TextBox. I figured the easiest way to do it would be to just listen for the TextChanged event and then set the TextBlock text to the value of the TextBox Text.
So I added the XAML:
<TextBox x:Name="input" TextChanged="input_TextChanged">Test Data</TextBox>
<TextBlock x:Name="output" />
I added the code-behind:
private void input_TextChanged(object sender, TextChangedEventArgs e)
{
output.Text = input.Text;
}
And I ran the application:
Well that’s a bit… unexpected!
So What Happened?
What happened is that when WPF adds the textbox to the control tree, it wires up the TextChanged event before it sets the default text, which causes the TextChanged event to fire. Since WPF hasn’t added the TextBlock to the control tree yet and it’s a null reference, my code that tries to set the text on that TextBlock fails, and an exception is born.
What’s unusual to me is that this is NOT the same behavior you would see in a Windows Forms application. If you recreate a similar application in Windows Forms with a TextBox and a Label, an exception is not thrown when the form is initialized. In fact, the TextChanged event is not even fired, it only starts firing after the form is up and running.
But back to the exception, how do you fix it?
If you want to solve the issue in code, you’ll need to check for null to avoid throwing an exception:
if ( output != null )
output.Text = input.Text;
But this isn’t optimal, as on the initial load you’ll have an empty TextBlock that’s not in sync with the TextBox. We can do better by eliminating the event handler completely and switching techniques to using data binding:
<TextBox x:Name="input">Test Data</TextBox>
<TextBlock x:Name="output" Text="{Binding ElementName=input, Path=Text}" />
And we now end up with exactly what we wanted: A TextBlock underneath a TextBox that stays in sync with the contents of the TextBox. Beautiful!
- Colin
78a900fd-8669-49fd-95ab-2c108ea6c09b|0|.0