Я следую шаблону M-V-VM для своего пользовательского интерфейса WPF. Я хотел бы связать команду с событием TextChanged в TextBox с командой, которая находится в моем классе ViewModel. Единственный способ, которым я могу решить эту задачу, - это унаследовать от элемента управления TextBox и реализовать ICommandSource. Затем я могу указать команду, которая должна запускаться из события TextChanged. Это кажется слишком большим трудом для чего-то, что кажется таким простым.
Есть ли более простой способ (чем создание подкласса TextBox и реализация ICommandSource) подключить событие TextChanged к моему классу ViewModel?





Разве вы не можете просто обработать событие TextChanged и оттуда выполнить команду?
private void _textBox_TextChanged(object sender, EventArgs e)
{
MyCommand.Execute(null);
}
Альтернативой, как вы говорите, является создание TextBox, который действует как источник команд, но это действительно кажется излишним, если только вы не планируете делиться этим и использовать во многих местах.
Во-первых, вы наверняка рассмотрели двустороннюю привязку данных к вашей модели просмотра с помощью UpdateSourceTrigger PropertyChanged? Таким образом, установщик свойства свойства, к которому вы привязываете, будет вызываться каждый раз при изменении текста?
Если этого недостаточно, я бы решил эту проблему с помощью Attached Behaviors. В блоге Джулиана Домингеса вы найдете статья о том, как сделать что-то очень похожее в Silverlight, которое должно быть легко адаптировано к WPF.
По сути, в статическом классе (называемом, скажем, TextBoxBehaviours) вы определяете присоединенное свойство, называемое (возможно) TextChangedCommand типа ICommand. Подключите обработчик OnPropertyChanged для этого свойства и внутри обработчика убедитесь, что свойство устанавливается в TextBox; если это так, добавьте обработчик к событию TextChanged в текстовом поле, который будет вызывать команду, указанную в свойстве.
Затем, предполагая, что ваша модель представления была назначена контексту данных вашего представления, вы должны использовать ее так:
<TextBox
x:Name = "MyTextBox"
TextBoxBehaviours.TextChangedCommand = "{Binding ViewModelTextChangedCommand}" />
Я не думаю, что добавление логики к установщику свойства сработает. Процессор WPF XAML использует свойство зависимостей напрямую, а не через оболочку свойств. Это означает, что установщик никогда не будет вызываться при обновлении пользовательского интерфейса. (источник: msdn.microsoft.com/en-us/library/bb613563.aspx)
Грег, я имею в виду средство задания свойства во ViewModel, к которому привязано свойство зависимости, а не средство задания самого свойства зависимости.
Использование привязки событий и командного метода может быть неправильным. Что именно будет делать эта команда?
Возможно, вы захотите использовать привязку данных к строковому полю в вашей виртуальной машине. Таким образом, вы можете вызывать команду или функцию оттуда, а не заботиться о пользовательском интерфейсе.
<TextBox Text = "{Binding WorldName}"/>
....
public string WorldName
{
get
{
return WorldData.Name;
}
set
{
WorldData.Name = value;
OnPropertyChanged("WorldName");
// CallYourCustomFunctionHere();
}
}
Спасибо, Нидоноку. Ваш ответ тоже идеален, но я отметил ответ Сэма как ответ, потому что он ответил немного раньше вашего. Еще раз спасибо!
Спасибо, Сэм - иногда я не вижу простых вариантов; в этом случае текстовое поле было привязано к строковому свойству в моей ViewModel.