I have a simple WM7 Page with a TextBox
. Futher, I assigned EventToCommand
(a RelayCommand<string>
) to this TextBox
, reacting to the TextChanged
event. For testing pourposes I made additional method TextBox_TextChanged
in the page's code behind. Both the command and TextBox_TextChanged
print a message box with the textbox content.
Initial value of the TextBox
is "ABC"
. Then I press D and:
TextBox_TextChanged
prints ABCD
.ABC
. D is missing.Why is the command so fast?
Command declaration:
public RelayCommand<string> TextChanged {get; private set;}
Command initialization:
TextChanged = new RelayCommand<string>((s) => MessageBox.Show(s));
Command binding:
<TextBox x:Name="SearchTextBox" Margin="10,0" TextWrapping="Wrap" Text="{Binding SearchString, Mode=TwoWay}" FontStyle="Italic" TextChanged="SearchTextBox_TextChanged" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding TextChanged, Mode=OneWay}" CommandParameter="{Binding Text, ElementName=SearchTextBox}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
I can't reproduce this behaviour. I have tried using EventToCommand and a Behaviour(which simply listens to TextChanged event).
Without seeing the code I suspect this might be to do with how you get the text of the search box or a logic error elsewhere.
This is a snippet of how I use EventToCommand:
<TextBox Name="SearchTextBox">
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<cmd:EventToCommand Command="{Binding TestTextChangedCommand,Mode=OneWay}" CommandParameter="{Binding Path=Text, ElementName=SearchTextBox}"/>
</i:EventTrigger>
<i:Interaction.Triggers>
</TextBox>
In the viewmodel
m_TestTextChangedCommand = new RelayCommand<string>(val => System.Diagnostics.Debug.WriteLine(val));
As you can see I used a commandparameter to pass the value of the textbox to the viewmodel. This way the viewmodel doesn't have to know about the textbox to get the text value.
An alternative to this approach would be to use behaviours and TwoWay binding to update a property:
<TextBox Name="SearchTextBox" Text="{Binding TextInViewModel, Mode=TwoWay}" >
<i:Interaction.Behaviors>
<sc:UpdateOnTextChangedBehavior/>
</i:Interaction.Behaviors>
</TextBox>
UpdateOnTextChangedBehavior class:
public class UpdateOnTextChangedBehavior : Behavior<TextBox>
{
protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.TextChanged +=
new TextChangedEventHandler(AssociatedObject_TextChanged);
}
void AssociatedObject_TextChanged(object sender, TextChangedEventArgs e)
{
System.Diagnostics.Debug.WriteLine(((TextBox)sender).Text);
BindingExpression binding =
this.AssociatedObject.GetBindingExpression(TextBox.TextProperty);
if (binding != null)
{
binding.UpdateSource();
}
}
protected override void OnDetaching()
{
base.OnDetaching();
this.AssociatedObject.TextChanged -=
new TextChangedEventHandler(AssociatedObject_TextChanged);
}
}
What the above does is mimick the behaviour of desktop WPF Binding
with UpdateSourceTrigger=PropertyChanged
, which is missing in Silverlight. So what will happen, whenever you type into the text box TextInViewModel
property will get updated. This property doesn't haven to be a DependencyProperty
, it could just be a normal CLR property.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With