2011-02-15 18 views
14

Tengo una colección de objetos vinculados a una plantilla de datos jerárquica, cada uno de mis objetos tiene una propiedad en ellos (vamos a llamarlo Propiedad "A") que es de cierto tipo . Este tipo varía entre cada uno de los objetos.WPF DataTemplate Enlace dependiendo del tipo de una propiedad

Si la plantilla de datos contiene una imagen y algo de texto, ¿cuál sería la mejor manera de cambiar la imagen que se muestra en la plantilla en función del tipo de propiedad "A".

Sé que podría simplemente pegar esto en un convertidor y hacer la traducción de enlace manualmente en el código, pero con todas las funciones de enlace disponibles en WPF, creo que hay probablemente una mejor manera.

Respuesta

31

Es bastante simple hacer esto dentro de su plantilla de datos, si crea plantillas de datos locales y usa un ContentPresenter. Esta plantilla presenta objetos de tipo MyObject, mostrando una imagen cuya fuente está determinada por el tipo de la propiedad A junto a un TextBlock que muestra el contenido de la propiedad Text:

<DataTemplate DataType="{x:Type MyObject}"> 
    <StackPanel Orientation="Horizontal"> 
     <StackPanel.Resources> 
     <DataTemplate DataType="{x:Type Thing1}"> 
      <Image Source="thing1.png"/> 
     </DataTemplate> 
     <DataTemplate DataType="{x:Type Thing2}"> 
      <Image Source="thing2.png"/> 
     </DataTemplate> 
     </StackPanel.Resources> 
     <ContentPresenter Content="{Binding A}"/> 
     <TextBlock Text="{Binding Text}"/> 
    </StackPanel> 
</DataTemplate> 

Si desea utilizar estilos de hacer esto, en su lugar, se encontrará con un problema, porque los desencadenadores de datos desean ver los valores de propiedad, y el tipo de la propiedad A no está, en sí mismo, expuesto como una propiedad.

A menos que, por supuesto, se implementa una:

public Type AType { get { return A.GetType(); } } 

(Usted también tendrá que aumentar PropertyChanged de AType cuando el valor de A cambios.) Una vez hecho esto, usted debe ser capaz para implementar un activador de datos en un estilo, por ejemplo:

<Style TargetType="Image"> 
    <Setter Property="Source" Value="default.png"/> 
    <Style.Triggers> 
     <DataTrigger Binding="{Binding AType}" Value="{x:Type Thing1}"> 
     <Setter Property="Source" Value="thing1.png"/> 
     </DataTrigger> 
     <DataTrigger Binding="{Binding AType}" Value="{x:Type Thing2}"> 
     <Setter Property="Source" Value="thing2.png"/> 
     </DataTrigger> 
    </Style.Triggers> 
</Style> 
1

Creo que puede hacerlo con triggers.

<Image.Style> 
    <Style TargetType="{x:Type Image}"> 
     <Setter Property="Source" Value="Path"> 
     <Style.Triggers> 
      <DataTrigger Binding="{Binding TheProperty}" Value="TheValue"> 
       <Setter Property="Source" Value="NewPath"/> 
      </DataTrigger> 
     </Style.Triggers> 
    </Style> 
</Image.Style> 
+0

Si uso un selector de plantilla de datos, ¿no necesitaría crear una nueva plantilla para cada tipo de elemento? – gmn

+0

Sí. Tal vez no entendí lo que estás tratando de hacer. Edité mi respuesta. –

1

DataTemplateSelector no parece ser una buena opción aquí ya que tiene la misma plantilla para todos los valores de A.

Uso DataTriggers:

<DataTemplate> 
    <StackPanel> 
     <Image x:Name="image" /> 
     <TextBlock>Your text</TextBlock> 
    </StackPanel> 
    <DataTemplate.Triggers> 
     <DataTrigger Binding="{Binding Path=A}" Value="ValueToCheck1"> 
      <DataTrigger.Setters> 
       <Setter Property="Source" Value="Image1.png" TargetName="image" /> 
      </DataTrigger.Setters> 
     </DataTrigger> 
     <DataTrigger Binding="{Binding Path=A}" Value="ValueToCheck2"> 
      <DataTrigger.Setters> 
       <Setter Property="Source" Value="Image2.png" TargetName="image" /> 
      </DataTrigger.Setters> 
     </DataTrigger> 
    </DataTemplate.Triggers> 
</DataTemplate> 

no lo he probado, pero la idea es así.

+0

Parece que esto no responde a la pregunta: "dependiendo del * tipo * de una propiedad". –

Cuestiones relacionadas