Hi,
I've got a very basic ViewModel that has a property
SearchText and a command
GetPersonsCommand:
private string _searchText;
public string SearchText
{
get
{
return _searchText;
}
set
{
if (value != this._searchText)
{
this._searchText = value;
OnPropertyChanged("SearchText");
}
}
}
public BaseCommand GetPersonsCommand { get; set; }
There's nothing fancy happening in BaseCommand, it's just a basic implementation of ICommand.
View:
In my view, I have a "Search" TextBox. I created a
Behavior that has a slight delay on TextChanged (allowing the user to type) and when they stop typing, my
GetPersonsCommand gets fired. This works.
<TextBox x:Name="txtSearch" Text="{Binding SearchText, Mode=TwoWay}">
<i:Interaction.Behaviors>
<b:DelayTextBox Command="{Binding GetPersonsCommand}" Interval="1000" />
</i:Interaction.Behaviors>
This is what happens: User types in TextBox -> When they stop typing GetPersonsCommand gets fired. Great so far...
My issue is that the first time the user types "John", the Command is fired, the SearchText property is still blank. Now the user types again "John Doe" and the SearchText property is now "John".
Why does the SearchText property only update itself after my Command is fired? In my head, when a user changes the text in the TextBox, because of the 2 way binding, the ViewModel's SearchText property should IMMEDIATELY be updated.
What am I doing wrong?
Here's my behavior, incase that matters....
public class DelayTextBox : Behavior<TextBox>
{
#region Properties
public ICommand Command
{
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}
public static readonly DependencyProperty CommandProperty =
DependencyProperty.Register("Command", typeof(ICommand), typeof(DelayTextBox), null);
public double Interval
{
get { return (double)GetValue(IntervalProperty); }
set { SetValue(IntervalProperty, value); }
}
public static readonly DependencyProperty IntervalProperty =
DependencyProperty.Register("Interval", typeof(double), typeof(DelayTextBox), new PropertyMetadata((s, e) =>
{
DelayTextBox parent = (DelayTextBox)s;
if (parent != null && parent._timer != null)
{
parent._timer.Stop();
parent._timer.Interval = TimeSpan.FromMilliseconds((double)e.NewValue);
}
}));
#endregion
private DispatcherTimer _timer;
protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.TextChanged += AssociatedObject_TextChanged;
this._timer = new DispatcherTimer();
this._timer.Tick += timer_Tick;
this._timer.Interval = TimeSpan.FromMilliseconds(this.Interval);
}
protected override void OnDetaching()
{
base.OnDetaching();
this.AssociatedObject.TextChanged -= AssociatedObject_TextChanged;
this._timer.Tick -= timer_Tick;
}
private void timer_Tick(object sender, EventArgs e)
{
this._timer.Stop();
if (this.Command != null)
{
this.Command.Execute(null);
}
}
private void AssociatedObject_TextChanged(object sender, TextChangedEventArgs e)
{
if (this._timer.IsEnabled)
{
this._timer.Stop();
this._timer.Start();
}
else
{
this._timer.Start();
}
}
}
Thanks in advance!