2011-04-12 14 views
6

Aquí está la explicación muy rápida y simplificada de mi situación. He definido un estilo para Hyperlink controles y tienen Command propiedad enganchan al comando definido en una clase ViewModel (simplificada):WPF: ¿Enlazar comandos en estilos y/o plantillas de datos (MVVM)?

<Window.Resources> 
    ... 
    <Style x:Key="hyperlinkStyle" TargetType="Hyperlink"> 
    ... 
    <Setter Property="Command" Value="{Binding Path=OpenHyperlinkCommand}" /> 
    ... 
    </Style> 
    ... 
</Window.Resources> 

A continuación, crea un control de contenido en la ventana estoy diseñando. Tiene una plantilla de datos definida, escrita en los recursos de la ventana. Dentro de esa plantilla de datos, agregué algunos hipervínculos y configuré esos hipervínculos para usar el estilo previamente definido.

La ventana se presenta (simplificado):

plantilla
<Window> 
    ... 
    <ContentControl 
     ... 
     ContentTemplate="{StaticResource myDataTemplate}" /> 
    ... 
</Window> 

Los datos se parece a esto (simplificado):

<Window.Resources> 
    ... 
    <DataTemplate x:Key="myDataTemplate DataType="{x:Type my:MyType}"> 
    ... 
    <TextBlock> 
     <Hyperlink 
      Style="{StaticResource hyperlinkStyle}" 
      CommandParameter="{Binding Path=Uri1}"> 
     <TextBlock Text="{Binding Path=Uri1}" /> 
     </Hyperlink> 
    </TextBlock> 
    ... 
    <TextBlock> 
     <Hyperlink 
      Style="{StaticResource hyperlinkStyle}" 
      CommandParameter="{Binding Path=Uri2}"> 
     <TextBlock Text="{Binding Path=Uri2}" /> 
     </Hyperlink> 
    </TextBlock> 
    ... 
    </DataTemplate> 
    ... 
</Window.Resources> 

La unión a la OpenHyperlinkCommand en el estilo no funciona porque el ViewModel de la ventana vinculada contiene este comando, pero el DataTemplate está vinculado a los objetos MyType, que no contienen este comando (ni deberían).

¿Cómo debo hacer que este enlace funcione? Dos preguntas:

  1. Aquí es mi propuesta: Me llamaba mi ventana x:Name="myWindow", y cambiaron la unión de el comando dentro del estilo a este:

    <Setter Property="Command" Value="{Binding ElementName=myWindow Path=DataContext.OpenHyperlinkCommand}" /> 
    

    Esto funciona, pero se ve tan sucio. ¿Estoy haciendo esto mal? ¿Hay una mejor manera, más como MVVM? ¡Esto es frágil porque estoy estableciendo un nombre de elemento específico dentro de un estilo!

  2. ¿Es una buena práctica escribir los enlaces de comando dentro de un estilo en el primer lugar ? Si no, ¿cuál es la alternativa? ¿Qué sucede si desarrollé un complejo UserControl, cómo podría establecer comandos para los componentes en algún lugar dentro de su árbol lógico?

¡Gracias por la ayuda!

Respuesta

16
  1. una sintaxis alternativa sería utilizar RelativeSource

    <Setter Property="Command" Value="{Binding DataContext.OpenHyperlinkCommand, RelativeSource={Relative Source AncestorType={x:Type Window}}}">

  2. No veo nada malo con fijaciones de comando de escritura en un estilo

+0

Esto acaba de hacer mi día .. . ¡Gracias! – danjarvis