2014-09-27 101 views
1

我有一个Textbox,它有一个KeyDown事件。该事件与ViewModel中的事件处理程序绑定。下面是示例代码:KeyDown事件的延迟计时器

<TextBox x:Name="textBox" Text="{Binding TextBoxText, UpdateSourceTrigger=PropertyChanged}"> 
    <i:Interaction.Triggers> 
     <i:EventTrigger EventName="KeyDown"> 
      <cmd:EventToCommand Command="{Binding Path=TextBoxKeyDownEvent}" PassEventArgsToCommand="True" /> 
     </i:EventTrigger> 
    </i:Interaction.Triggers> 
<TextBox.InputBindings> 

这是事实,一旦用户开始在texbox写作,在视图模型后端调用事件处理程序。但我不想为每个KeyDown操作调用事件处理程序。我想在用户开始在文本框中输入并停止至少N毫秒时调用事件处理函数。这意味着我需要为事件设置一个延迟计时器。任何人都可以请指导我如何在MVVM中实现这一点?

回答

4

您可以使用BindingBase.Delay属性:

<TextBox x:Name="textBox" Text="{Binding TextBoxText, Delay=500, UpdateSourceTrigger=PropertyChanged}" /> 

这将修改TextBoxText财产在你的视图模型已经被用户更改只有500毫秒后。然后,在你的setter中,你可以调用你想要执行的任何代码。

private string textBoxText; 
public string TextBoxText 
{ 
    get { return textBoxText; } 
    set 
    { 
     // Setter will be called only 500 milliseconds after the user has entered text. 
     if (textBoxText != value) 
     { 
      textBoxText = value; 
      RaisePropertyChanged("TextBoxText"); 

      // Handle text change. 
      DoStuff(); 
     } 
    } 
} 

编辑:

如果您希望在属性中的代码被改变的延迟也发生了,你可以使用类似的解决方案在这里提到的某些东西:Timer to fire an event WPF

+0

感谢您的建议。但是我无法在TextProperty Change事件中使用它。因为文本可以由程序在内部进行更改。所以这里的事件处理程序只有在文字变化通过写入才会发生。这就是为什么我需要与keydown事件合作。 – ifti24 2014-09-27 14:10:38

+0

@ ifti24请参阅我的编辑 – 2014-09-27 14:15:16

+0

我想我没有让你明白目的。我有一个TextBox,并且在每个Keypress的TextBox中都有一个命令绑定。 Binded方法调用视图和视图从数据库中获取数据。但我不希望每个按键都会调用绑定的方法。我想,如果用户停止键入一定的时间(如500毫秒),只有绑定的方法将被调用。 – ifti24 2014-09-27 14:42:23

0

设置一个定时器和超时事件

private System.Timers.Timer keypressTimer = new System.Timers.Timer(); 
    keypressTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent); 

在超时事件内部执行您的任务 -

private void OnTimedEvent(object source, ElapsedEventArgs e) 
    { 
     keypressTimer.Stop(); 
     App.Current.Dispatcher.Invoke((Action)delegate 
     { 

      //CALL YOUR EVENT HERE 

     }); 

    } 

每次按键 - 您需要按以下方式重置计时器。

if (delayTime > 0) 
      { 
       keypressTimer.Interval = delayTime; 
       keypressTimer.Start(); 
      }