TextBox.TextChanged event firing twice on Windows Phone 7 emulator

The reason the TextChanged event fires twice in WP7 is a side effect of how the TextBox has been templated for the Metro look.

If you edit the TextBox template in Blend you will see that it contains a secondary TextBox for the disabled/read-only state. This causes, as a side effect, the event to fire twice.

You can change the template to remove the extra TextBox (and associated states) if you don't need these states, or modify the template to achieve a different look in the disabled/read-only state, without using a secondary TextBox.

With that, the event will fire only once.


i'd go for the bug, mainly because if you put the KeyDown and KeyUp events in there, it shows that that they are fired only once (each of them) but the TextBoxChanged event is fired twice


That does sound like a bug to me. As a workaround, you could always use Rx's DistinctUntilChanged. There is an overload that allows you to specify the distinct key.

This extension method returns the observable TextChanged event but skips consecutive duplicates:

public static IObservable<IEvent<TextChangedEventArgs>> GetTextChanged(
    this TextBox tb)
{
    return Observable.FromEvent<TextChangedEventArgs>(
               h => textBox1.TextChanged += h, 
               h => textBox1.TextChanged -= h
           )
           .DistinctUntilChanged(t => t.Text);
}

Once the bug is fixed you can simply remove the DistinctUntilChanged line.


Nice! I found this question by searching for a related problem and also found this annoying thing in my code. Double event eats more CPU resources in my case. So, I fixed my real-time filter textbox with this solution:

private string filterText = String.Empty;

private void SearchBoxUpdated( object sender, TextChangedEventArgs e )
{
    if ( filterText != filterTextBox.Text )
    {
        // one call per change
        filterText = filterTextBox.Text;
        ...
    }

}

I believe this has always been a bug in the Compact Framework. It must have been carried over into WP7.