2008-09-11 12 views
9

Estoy siguiendo el patrón M-V-VM para mi interfaz de usuario de WPF. Me gustaría conectar un comando al evento TextChanged de un TextBox a un comando que está en mi clase ViewModel. La única forma en que puedo concebir completar esta tarea es heredar del control TextBox e implementar ICommandSource. Luego puedo ordenar al comando que se active desde el evento TextChanged. Esto parece ser demasiado trabajo para algo que parece ser tan simple.TextBox.TextChanged & ICommandSource

¿Existe alguna manera más fácil (que subclasificar el TextBox e implementar ICommandSource) para conectar el evento TextChanged a mi clase ViewModel?

Respuesta

18

En primer lugar, seguramente ha considerado el enlace de datos bidireccional a su modelo de vista, con un UpdateSourceTrigger de PropertyChanged? De esta forma, ¿se llamará al establecimiento de la propiedad a la que se vincula cada vez que se cambie el texto?

Si eso no es suficiente, entonces abordaría este problema utilizando Comportamientos adjuntos. En el blog de Julian Domínguez encontrará un article sobre cómo hacer algo muy similar en Silverlight, que debería ser fácilmente adaptable a WPF.

Básicamente, en una clase estática (llamada, digamos TextBoxBehaviours) define una propiedad adjunta llamada (quizás) TextChangedCommand de tipo ICommand. Conecte un controlador OnPropertyChanged para esa propiedad, y dentro del controlador, verifique que la propiedad se establezca en un TextBox; si es así, agregue un controlador al evento TextChanged en el cuadro de texto que llamará al comando especificado en la propiedad.

Entonces, asumiendo que su modelo de vista ha sido asignado a la DataContext de la vista, que lo utilizaría como:

<TextBox 
    x:Name="MyTextBox" 
    TextBoxBehaviours.TextChangedCommand="{Binding ViewModelTextChangedCommand}" /> 
+1

Gracias Sam - a veces no veo las opciones simples; que en este caso tenía el cuadro de texto vinculado a una propiedad de cadena en mi ViewModel. –

+0

No creo que agregue lógica al colocador de la propiedad funcionaría. El procesador XAML de WPF usa la propiedad de dependencia directamente en lugar de pasar por el contenedor de propiedades. Esto significa que nunca se llamará al colocador cuando se actualice la IU. (fuente: http://msdn.microsoft.com/en-us/library/bb613563.aspx) – Greg

+2

Greg, me refiero al Setter de la propiedad en el ViewModel al que está vinculada la propiedad de dependencia, no al establecedor de la propiedad de dependencia en sí. –

3

¿No puedes manejar el evento TextChanged y ejecutar el comando desde allí?

private void _textBox_TextChanged(object sender, EventArgs e) 
{ 
    MyCommand.Execute(null); 
} 

La alternativa, como usted dice, es crear un TextBox que actúa como una fuente de comandos, pero eso no parecer demasiado difícil a menos que sea algo que se está pensando en compartir y aprovechar en muchos lugares.

8

Utilizando el proceso de unión y el método de comando podría no ser lo correcto a utilizar. ¿Qué hará exactamente este comando?

Es posible que desee considerar el uso de un enlace de datos a un campo de cadena en su máquina virtual. De esta forma, puede realizar una llamada a un comando o función desde allí en lugar de tener cuidado de la IU en absoluto.

<TextBox Text="{Binding WorldName}"/> 
.... 
public string WorldName 
{ 
    get 
    { 
     return WorldData.Name; 
    } 
    set 
    { 
     WorldData.Name = value; 
     OnPropertyChanged("WorldName"); 
     // CallYourCustomFunctionHere(); 
    } 
} 
+0

Gracias Nidonocu. Tu respuesta también es perfecta, pero marqué la respuesta de Sam como la respuesta porque respondió ligeramente antes que la tuya. ¡Gracias de nuevo! –