How to make Silverlight TextBox.TextChanged event fire synchronously?
Platform: Silverlight 4 / .NET 4
Description:
I have a ComboBox
, a Textbox
and a NumericUpDown
.
<StackPanel Margin="10">
<ComboBox SelectionChanged="cmbChanged" Margin="3">
<ComboBoxItem Content="A" />
<ComboBoxItem Content="B" />
</ComboBox>
<TextBox x:Name="txt" TextChanged="txtChanged" Margin="3"/>
<CheckBox x:Name="chk" Checked="chkChecked" Unchecked="chkChecked" Content="Check box" Margin="3"/>
<ListBox x:Name="lst" Height="100" Margin="3"/>
</StackPanel>
A list is for debugging purposes.
Repro:
Note that there are event handlers for TextBox.TextChanged
, CheckBox.Checked
, CheckBox.Unchecked
and ComboBox.SelectionChanged
.
Here are the handlers:
private void cmbChanged(object sender, SelectionChangedEventArgs e)
{
lst.Items.Clear();
txt.Text = (sender as ComboBox).SelectedIndex.ToString();
chk.IsChecked = !c开发者_Python百科hk.IsChecked;
}
private void txtChanged(object sender, TextChangedEventArgs e)
{
lst.Items.Add("Text Changed");
}
private void chkChecked(object sender, RoutedEventArgs e)
{
bool? chk = (sender as CheckBox).IsChecked;
lst.Items.Add("CheckBox Changed to " + chk);
}
Problem:
In the combobox's event handler, I set the text in the textbox BEFORE setting the check state of the checkbox. However, if you take a look at the picture below, you will see that the event handler for the CheckBox.Checked
gets called before TextBox.TextChanged
.
The problem is obviously in the asynchronous execution of the TextBox.TextChanged event, as stated in the MSDN definition:
The TextChanged event is asynchronous. The event cannot be canceled.
I really need these event handlers to execute exactly in the order they are changed.
Question: Is there any simple way to achieve what I need?
Perhaps it might be better to call your piece of business logic directly, instead of relying on the event handlers. You can always remove and add the EventHandler in case you don't want to hit that trigger in your particular situation:
//Remove event handlers:
CheckBox.Checked -= chkChecked;
TextBox.TextChanged -= txtChanged;
//Call your business stuff here
//You can also 'safely' set values on your textbox and
//checkbox since they wont trigger events now.
//Re-add event handlers, so they react on user input again:
CheckBox.Checked += chkChecked;
TextBox.TextChanged += txtChanged;
I'm not a Silverlight guy so these are suggestions:
Use the KeyDown/KeyUp events to capture changes to your text box.
Use the FocusManager to manage synchronous GotFocus/LostFocus events and check for changes there.
精彩评论