问题
I am following the M-V-VM pattern for my WPF UI. I would like to hook up a command to the TextChanged event of a TextBox to a command that is in my ViewModel class. The only way I can conceive of completing this task is to inherit from the TextBox control, and implement ICommandSource. I can then instruct the command to be fired from the TextChanged event. This seems to be too much work for something which appears to be so simple.
Is there an easier way (than subclassing the TextBox and implementing ICommandSource) to hook up the TextChanged event to my ViewModel class?
回答1:
First off, you've surely considered two-way data binding to your viewmodel, with an UpdateSourceTrigger of PropertyChanged? That way the property setter of the property you bind to will be called every time the text is changed?
If that's not enough, then I would tackle this problem using Attached Behaviours. On Julian Dominguez’s Blog you'll find an article about how to do something very similar in Silverlight, which should be easily adaptable to WPF.
Basically, in a static class (called, say TextBoxBehaviours) you define an Attached Property called (perhaps) TextChangedCommand of type ICommand. Hook up an OnPropertyChanged handler for that property, and within the handler, check that the property is being set on a TextBox; if it is, add a handler to the TextChanged event on the textbox that will call the command specified in the property.
Then, assuming your viewmodel has been assigned to the DataContext of your View, you would use it like:
<TextBox
x:Name="MyTextBox"
TextBoxBehaviours.TextChangedCommand="{Binding ViewModelTextChangedCommand}" />
回答2:
Using the event binding and command method might not be the right thing to use. What exactly will this command do?
You might want to consider using a Databinding to a string field in your VM. This way you can make a call to a command or function from there rather than having the UI care at all.
<TextBox Text="{Binding WorldName}"/>
....
public string WorldName
{
get
{
return WorldData.Name;
}
set
{
WorldData.Name = value;
OnPropertyChanged("WorldName");
// CallYourCustomFunctionHere();
}
}
回答3:
Can you not just handle the TextChanged event and execute the command from there?
private void _textBox_TextChanged(object sender, EventArgs e)
{
MyCommand.Execute(null);
}
The alternative, as you say, is to create a TextBox
that acts as a command source, but that does seem like overkill unless it's something you're planning on sharing and leveraging in many places.
来源:https://stackoverflow.com/questions/55855/textbox-textchanged-icommandsource