TextBox.TextChanged事件在Windows Phone 7模拟器上触发两次

Jon*_*eet 90 c# silverlight xaml textbox windows-phone-7

我有一个非常简单的测试应用程序,只是为了玩Windows Phone 7.我刚刚添加了一个TextBox和一个TextBlock标准的UI模板.唯一的自定义代码如下:

public partial class MainPage : PhoneApplicationPage
{
    public MainPage()
    {
        InitializeComponent();
    }

    private int counter = 0;

    private void TextBoxChanged(object sender, TextChangedEventArgs e)
    {
        textBlock1.Text += "Text changed " + (counter++) + "\r\n";
    }
}
Run Code Online (Sandbox Code Playgroud)

TextBox.TextChanged事件TextBoxChanged在XAML中连接到:

<TextBox Height="72" HorizontalAlignment="Left" Margin="6,37,0,0"
         Name="textBox1" Text="" VerticalAlignment="Top"
         Width="460" TextChanged="TextBoxChanged" />
Run Code Online (Sandbox Code Playgroud)

但是,每当我在模拟器中运行时按一个键(屏幕键盘或物理键盘,按下Pause以启用后者),它会使计数器递增两次,显示两行TextBlock.我尝试的所有东西都表明这个事件真的发射了两次,我不知道为什么.我已经验证它只被订阅了一次 - 如果我在MainPage构造函数中取消订阅,当文本改变时,根本没有任何事情发生(对于文本块).

我在常规的Silverlight应用程序中尝试过等效的代码,并没有在那里发生.目前我没有手机可以重现这一点.我还没有找到任何关于Windows Phone 7中已知问题的记录.

任何人都可以解释我做错了什么,或者我应该将此报告为错误?

编辑:为了减少这两个文本控件的可能性,我已经尝试TextBlock完全删除,并将TextBoxChanged方法更改为只是增量counter.然后我在模拟器中运行,键入10个字母,然后counter++;在行上放置一个断点(只是为了摆脱闯入调试器导致问题的任何可能性) - 它显示counter为20.

编辑:我现在已经在Windows Phone 7论坛中询问过 ......我们会看到会发生什么.

Ste*_*SFT 75

TextChanged事件在WP7中两次触发的原因是TextBox对于Metro外观如何模板化的副作用.

如果TextBox在Blend中编辑模板,您将看到它包含TextBox禁用/只读状态的辅助模板.作为副作用,这会导致事件发生两次.

您可以更改模板删除多余的TextBox(和相关联的状态),如果你不需要这些状态,或者修改模板,实现残疾人/只读状态不同的外观,而无需使用二次TextBox.

有了这个,该事件将只发射一次.


und*_*ror 18

我会去找bug,主要是因为如果你把那些KeyDownKeyUp事件放在那里,它表明它们只被触发一次(每个都被触发)但TextBoxChanged事件被触发了两次


Ric*_*lay 8

这对我来说听起来像个错误.作为一种解决方法,您可以随时使用Rx DistinctUntilChanged.有一个重载允许您指定不同的键.

此扩展方法返回可观察的TextChanged事件,但跳过连续的重复项:

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);
}
Run Code Online (Sandbox Code Playgroud)

修复错误后,您只需删除该DistinctUntilChanged行即可.