2011-02-15 110 views
14

我有一个绑定到分层数据模板的对象集合,每个对象都有一个属性(让我们称之为属性“A”),它属于某种类型。这种类型在每个对象中都有所不同。WPF DataTemplate根据属性的类型进行绑定

如果数据模板包含图像和某些文本,则根据属性“A”的类型更改模板中显示的图像的最佳方式是什么。我知道我可以将它粘贴到转换器中,并在代码中手动执行绑定转换,但是通过WPF中提供的所有绑定工具,我认为这可能是更好的方法。

回答

31

如果您创建本地数据模板并使用ContentPresenter,在数据模板中执行此操作非常简单。这个模板呈现MyObject类型的对象,显示图像,其来源是由显示Text属性的内容旁边TextBlock类型的A属性决定:

<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> 

如果要使用样式做相反,您将遇到问题,因为数据触发器想要查看属性值,并且A属性的类型本身不作为属性公开。

除非,当然,你实现一个:

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

(你还需要提高PropertyChangedATypeA变化值。)一旦你这样做,你应该能够以实现一种风格,例如数据触发:

<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

我想你可以用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

如果我使用一个数据模板选择,不会我需要为每种类型的项目一个新的模板? – gmn 2011-02-15 23:02:31

+0

是的。也许我误解了你想要做什么。我编辑了我的答案。 – 2011-02-15 23:05:16

1

DataTemplateSelector似乎并不在这里是一个很好的选择,因为你必须为A所有值相同的模板。

使用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> 

没有测试它,但这个想法是这样的。

相关问题