2010-08-14 21 views
7

Estoy usando MVVM y la capa ViewModel proporciona objetos ICommand personalizados. Un objeto ViewModel al mismo tiempo se puede conectar a través de la propiedad DataContext a muchos objetos de visualización (ventanas, páginas, etc.). En ICommand.CanExecute(), deseo verificar la ausencia de errores de validación para algunos controles en la Vista (que se adjunta a las características de ViewModel, significativas para un comando VM particular). Un ViewModel puede proporcionar muchos comandos, cada uno de ellos tiene su propio conjunto de controles para la verificación de validación de errores. Por lo tanto, la pseudo-XAML es:WPF: ¿Cómo pasar Control completo como parámetro de comando a través de XAML?

<Button.CommandParameter> 
    <x:Array Type="sys_win:DependencyObject"> 
     <sys_win:DependencyObject> 
      <reference_to_textbox_or_other_control/> 
     </sys_win:DependencyObject> 
     <sys_win:DependencyObject> 
      <reference_to_textbox_or_other_control/> 
     </sys_win:DependencyObject> 
    </x:Array> 
</Button.CommandParameter> 

El segundo problema es que el comando en particular puede ser invocada por el control, que a su vez es la parte de la DataTemplate de elemento de la colección (en mi caso - parte de la plantilla de datos ListBoxItem) . Mi elemento de cuadro de lista con plantilla tiene dos cuadros de texto (vinculados a dos apoyos de ViewModel correspondiente) y un botón, que invocan el comando ViewModel. Por lo tanto, al comando CanExecute() necesito verificar si hay errores de validación para algunos controles de ventana & dos cuadros de texto, que pertenecen a este elemento de lista, no a otros elementos. El código siguiente funciona bien si quiero pasar a la propiedad ListBoxItem.IsSelected como CommandParameter:

<Button DataContext="{Binding}" 
     Command="{Binding Path=SwitchCommand}" 
     CommandParameter="{Binding Path=IsSelected, RelativeSource={ 
            RelativeSource 
            Mode=FindAncestor, 
            AncestorType={x:Type ListBoxItem}}}"/> 

Pero, ¿cómo puedo pasar toda (DependencyObject) ListBoxItem como el CommandParameter? ¿Y cómo este ListBoxItem, pasado a través de {Binding RelativeSource} se puede mezclar con otros controles de ventana actuales en el primer ejemplo de código?


Lo siento mucho, pero ¿cómo puedo agregar las referencias a los controles en xaml?

<Button.CommandParameter> 
    <x:Array Type="sys_win:DependencyObject"> 
     <sys_win:DependencyObject> 
      <reference_to_textbox_or_other_control/> 
     </sys_win:DependencyObject> 
     <sys_win:DependencyObject> 
      <reference_to_textbox_or_other_control/> 
     </sys_win:DependencyObject> 
    </x:Array> 
</Button.CommandParameter> 
+0

StackOverflow no es un foro; si necesita agregar más detalles, por favor [edite su pregunta] (http://stackoverflow.com/posts/3482343/edit). Se supone que las respuestas son respuestas, no información adicional sobre la pregunta. – Will

Respuesta

23

sólo tiene que utilizar una unión sin Path:

<Button DataContext="{Binding}" 
     Command="{Binding Path=SwitchCommand}" 
     CommandParameter="{Binding RelativeSource= 
            {RelativeSource 
            Mode=FindAncestor, 
            AncestorType={x:Type ListBoxItem}}}"/> 
+0

Thomas Levesque, gracias. Su funcionamiento, :) –

1

No estoy seguro de si estoy leyendo tu ejemplo correctamente, pero parece violar un poco del principio MVVM. (Mis disculpas si lo leo incorrectamente).

La idea detrás de MVVM es desacoplar el modelo de vista de cualquier dependencia en una entidad XAML/View. Está rompiendo eso al tener CommandParameter dependiendo del control de usuario. Lo que haría sería crear propiedades de estado en ViewModel y vincular las validaciones de control de usuario a esos estados, luego en CanExecute puede probar los valores de esas propiedades en lugar de intentar enlazar con un control de usuario.

+0

Doobi, el inglés no es mi lengua materna, lo sabía bastante mal de lo normal, por lo que su comprensión parcialmente incorrecta de la primera publicación es culpa mía :) ViewModel proporciona comandos, que utiliza propiedades también provisto por ViewModel. Las propiedades estaban obligadas a Ver los controles y la validación de errores proporcionados a través de IDataErrorInfo, cuya implementación también forma parte de ViewModel. A pesar de que en Ver todos los valores de error marcados con una plantilla especial, el usuario puede intentar invocar uno de los comandos de ViewModel, que utiliza propiedades con valores de error (actualmente). Para bloquear esta habilidad, conectamos en ICo –

+0

ICommand.Execute(), verificamos todas las propiedades, qué valores usa este comando. Por lo tanto, verificamos las propiedades de ViewModel para los errores dos veces: 1) en la cadena IDataErrorInfo.this [string propertyName] cuando se cambia el valor de propiedad 2) en ICommand.CanExecute cuando actualización del motor WPF IU Para evitar la implementación (2) deseo transmitir la lista de controles de vista (vinculados a las propiedades del ViewModel, que son significativos para el comando ViewModel actual) en ICommand.CanExecute como CommandParameter y verificar errores a través de Validation.GetHasError (DependencyObject). –

+0

Debido a que Command recibe la lista de DependencyObjects, ViewModel permanece independiente de View. Pero hoy, después de pensarlo mucho, llegué a la conclusión de que mi enfoque es como la invención de la rueda cuadrada y rechacé esta idea. –

Cuestiones relacionadas