0

我对计时器和 AutocompleteBox 工具包有疑问。我有带有 TextChanged 事件的 AutoCompletebox。在此事件中,我启动计时器以使过滤更顺畅(当用户写入时,过滤器不起作用)。当我写的时候一切正常,但是当我从下拉列表中选择 TextChanged 事件时,我没有计时器 Tick 事件(过滤器不启动)。我做错了什么?

xml:

<Controls:AutoCompleteBox Name="acbIdentyfikatorPcS" ValueMemberPath="Identyfikator" FilterMode="Contains" HorizontalAlignment="Left" Margin="100,5,0,0" Grid.Row="1" VerticalAlignment="Top" Width="121" ToolTip="Identyfikator" MinimumPrefixLength="0" TextChanged="acbSerwisant_TextChanged" IsTextCompletionEnabled="True">
                    <Controls:AutoCompleteBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Margin="0,0,10,0" FontWeight="Bold" Text="{Binding Identyfikator}"></TextBlock>
                        </DataTemplate>
                    </Controls:AutoCompleteBox.ItemTemplate>
                </Controls:AutoCompleteBox>

CS:声明:

private DispatcherTimer timerfiltr = new DispatcherTimer();
private DataTable PcS;  

public MainWindow()
{
    InitializeComponent();
    timerfiltr.Tick += new EventHandler(timerfiltr_Tick);
    timerfiltr.Interval = new TimeSpan(0, 0, 0, 0, 400);
} 


private void acbSerwisant_TextChanged(object sender, RoutedEventArgs e)
{
    timerfiltr.Stop();
    timerfiltr.IsEnabled = true;
    timerfiltr.Start();     
}

private void timerfiltr_Tick(object sender, EventArgs e)
{
    PcS.DefaultView.RowFilter = "Identyfikator like '%" + acbIdentyfikatorPcS.Text + "%'";
    timerfiltr.Stop();
    timerfiltr.IsEnabled = false;            
}

编辑:

我想我发现了我的问题:这个 AutoCompleteBox 在 TabItem 之一上,我也有 TabControl SelectionChanged 事件,其中还有 timer.stop() 命令

 private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
    //rest of code
           // timerfiltr.Stop();
    }

当我按下键盘上的键(AutoCompleteBox 聚焦)时,DropDown 打开,然后 TabControl SelectionChanged 事件也启动和停止计时器......奇怪

4

2 回答 2

0

我没有测试您的示例代码,我认为 *acbSerwisant_TextChanged* 可能会停止调度程序线程。对于这种情况,我建议您像这样更改您的代码,也许不是最好的,但应该可以工作,并且有一个更适合处理这种情况的框架,称为“RX”(https://rx.codeplex.com),方法 Throttle 是你想要的。

**更新:如果你担心性能,添加标志作为开关,因为所有代码都在ui线程下运行,这保证你最后的文本更改将被接受。但现实有点复杂,通常你会在另一个线程中过滤...如果发生这种情况,我建议您使用带有 while 语句的其他线程来检查 textchange,或者您可以查看 RX。

private bool enableFilter;
public MainWindow()
{
  InitializeComponent();
  timerfiltr.Tick += new EventHandler(timerfiltr_Tick);
  timerfiltr.Interval = new TimeSpan(0, 0, 0, 0, 400);

  acbIdentyfikatorPcS.GotFocus +=(s,e)=>{timerfiltr.Start();};
  acbIdentyfikatorPcS.LostFocus +=(s,e)=>{timerfiltr.Stop();};

  acbIdentyfikatorPcS.TextChanged +=(s,e)=>{enableFilter= true;};

} 

private void timerfiltr_Tick(object sender, EventArgs e)
{
    if(enableFilter)
    {
        enableFilter= false;           
        //do filter

    }
}
于 2013-11-11T08:58:39.773 回答
0

您可以使用 AutoCompleteBox 的 IsDropDownOpen 属性(或 DropDownXXX 事件)来确定 DropDown 当前是否可见,一种快速的解决方案是避免在其 Tick 方法中停止计时器。

于 2013-11-11T08:11:35.233 回答