Reputation: 191
I have a Textbox
that has a KeyDown
event. This Event is bound with an event handler in the ViewModel. Below is the sample code:
<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>
It is true that as soon as the user starts writing in the texbox, the backend event handler in ViewModel is called. But I don't want to call the event handler for each KeyDown operation. I want to call the event handler when the user starts typing in the textbox and stops for at least N milliseconds. That means I need to set a delay timer for the event. Can anyone please guide me how I can achieve that in MVVM?
Upvotes: 2
Views: 1534
Reputation: 191
Set a timer and a Time out Event
private System.Timers.Timer keypressTimer = new System.Timers.Timer();
keypressTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
Inside the timeout event do your task -
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
keypressTimer.Stop();
App.Current.Dispatcher.Invoke((Action)delegate
{
//CALL YOUR EVENT HERE
});
}
Each time the key will be press - you need to reset the timer in the following way.
if (delayTime > 0)
{
keypressTimer.Interval = delayTime;
keypressTimer.Start();
}
Upvotes: 1
Reputation: 25201
You can make use of the BindingBase.Delay
property:
<TextBox x:Name="textBox" Text="{Binding TextBoxText, Delay=500, UpdateSourceTrigger=PropertyChanged}" />
This will modify the TextBoxText
property in your viewmodel only 500 milliseconds after it has been changed by the user. Then, in your setter you can call any code you'd like to execute.
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();
}
}
}
EDIT:
If you want the delay to happen also when the property is changed in the code, you could use something similar to the solution mentioned here: Timer to fire an event WPF
Upvotes: 7