Как заставить событие Silverlight TextBox.TextChanged запускаться синхронно? - PullRequest
2 голосов
/ 19 июля 2011

Платформа: Silverlight 4 / .NET 4

Описание:

У меня есть ComboBox, Textbox и 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>

Список предназначен для отладки.

Репро:

Обратите внимание, что есть обработчики событий для TextBox.TextChanged, CheckBox.Checked, CheckBox.Unchecked и ComboBox.SelectionChanged.

Вот обработчики:

private void cmbChanged(object sender, SelectionChangedEventArgs e)
{
    lst.Items.Clear();
    txt.Text = (sender as ComboBox).SelectedIndex.ToString();
    chk.IsChecked = !chk.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);
}

Проблема:

В обработчике событий комбобокса я установил текст в текстовом поле ДО , установив состояние проверки флажка. Однако, если вы посмотрите на рисунок ниже, вы увидите, что обработчик событий для CheckBox.Checked вызывается до TextBox.TextChanged.

TextBox.TextChanged occurs asynchronously

Проблема, очевидно, заключается в асинхронном выполнении события TextBox.TextChanged , как указано в определении MSDN :

Событие TextChanged является асинхронным. Событие не может быть отменено.

Мне действительно нужно, чтобы эти обработчики событий выполнялись точно в том порядке, в котором они изменены.

Вопрос: Есть ли простой способ добиться того, что мне нужно?

Ответы [ 2 ]

1 голос
/ 19 июля 2011

Возможно, было бы лучше вызвать вашу часть бизнес-логики напрямую, а не полагаться на обработчики событий.Вы всегда можете удалить и добавить EventHandler, если вы не хотите нажимать на этот триггер в вашей конкретной ситуации:

//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;
0 голосов
/ 19 июля 2011

Я не парень из Silverlight, так что это предложения:

Используйте события KeyDown / KeyUp, чтобы зафиксировать изменения в вашем текстовом поле.
Используйте FocusManager для управления синхронными событиями GotFocus / LostFocus и проверки изменений там.

...