2010-06-03 16 views

Respuesta

15

Esta es una de esas respuestas en las que no respondo a su pregunta, sino que le doy una conferencia acerca de lo que debería estar haciendo diferente. Lamento mucho eso. Aquí va:

Si se encuentra en una posición en la que necesita llegar al objeto emisor en su modelo de vista, entonces probablemente debería hacer algo diferente. Al hacer referencia, por ejemplo, a un Botón o a un ListBox en su modelo de vista, ha hecho que ese modelo de vista tenga en cuenta los conceptos de la interfaz de usuario de los que no debería saber nada. Mi sugerencia es conectar el evento en la página de código subyacente, averiguar qué necesita saber sobre el remitente o qué no, y luego ejecutar el comando viewmodel mediante programación. Eso también está rompiendo las "reglas" de MVVM, pero en mi humilde opinión es un truco mucho más ligero que hacer referencia al remitente en tu modelo de vista.

+0

Al igual que la máquina virtual no debe exponer visibilidad (y en su lugar utilizar un convertidor en el XAML), tal vez no debería haber alguna forma de utilizar un convertidor para ir a otro lado ... convertir de un punto de vista basado eventarg en un tipo sin vista? –

+0

¿Cómo es que tu sugerencia también está rompiendo las reglas de MVVM? Me parece bien. –

+0

Creo que mi principal problema en ese momento era que es demasiado complicado en comparación con solo vincular el botón (en la vista) al comando en la máquina virtual. Mirándolo ahora, creo que tienes razón. Realmente no rompe ninguna regla. –

9

Estaba teniendo un problema similar, pero solo necesitaba obtener los EventArgs. Con mucho gusto, esto fue absurdamente simple una vez que encontré la respuesta en otro hilo aquí en Stack Overflow.

<cmd:EventToCommand Command="{Binding SomeCommand, Mode=OneWay}" PassEventArgsToCommand="True"/> 

Una vez que sabes acerca de que la magia "PassEventArgsToCommand" ajuste, que es de oro. Solo use un RelayCommand<type> en lugar de un simple RelayCommand.

Espero que esto ayude.

+5

Solo quiero comentar sobre eso: PassEventArgsToCommand no es muy limpio, ya que rompe la separación de preocupaciones al traer una clase UI (EventArgs) a la VM. Usar esto hace que tu VM sea menos comprobable. Sin embargo, hay escenarios (arrastrar y soltar, por ejemplo) donde cualquier otra cosa sería aún más sucio. Es por eso que agregué esto en EventToCommand. Sin embargo, ¡utilízalo con mucho cuidado! – LBugnion

+2

Aunque PassEventArgsToCommand puede no estar limpio, me pareció útil intentar agregar compatibilidad con SkyDrive a mi aplicación WP7. El botón de inicio de sesión pasa la información de la sesión en vivo a través de los argumentos del evento. Probablemente podría manejar el evento en código subyacente, establecer la propiedad Session en ViewModel y luego invocar un comando. El PassEventArgsToCommand ayuda a escribir código comprensible. – rams

5

Esto se puede hacer vinculando el remitente al parámetro de comando.

<command:EventToCommand 
       Command="{Binding CommandName}" 
       CommandParameter="{Binding RelativeSource= 
             { RelativeSource FindAncestor, 
              AncestorType={x:Type TypeOfSender}, 
              AncestorLevel=1}}" 
       PassEventArgsToCommand="True" > 
</command:EventToCommand> 
+1

Subí esto porque aunque Henrik tiene razón al explicar que esto no debe hacerse, el mundo no es perfecto y lograr VMVM puro a veces es imposible. Por ejemplo, si desea que Textbox seleccione todo el texto cuando recibe el foco, necesitará el propio TextBox para llamar a su miembro SelectAll(). Es, sin duda, factible en MVVM, pero creará un código increíblemente complejo, mientras que esta solución es, en algunas situaciones, "lo suficientemente buena". Estoy de acuerdo en que se debe desalentar este comportamiento tanto como sea posible, pero a veces solo se necesita ser pragmático y una solución como esta, aunque fea, funciona. – Bas

+2

Otro ejemplo: el control WPF WebBrowser. puede vincular un comando al evento Navegado, pero si realmente desea hacer algo con la respuesta http, necesita una referencia al navegador en sí, porque esa información no está en el eventargs. – Bas

Cuestiones relacionadas