WPF DataTemplate 绑定取决于属性的类型

Posted

技术标签:

【中文标题】WPF DataTemplate 绑定取决于属性的类型【英文标题】:WPF DataTemplate Binding depending on the type of a property 【发布时间】:2011-06-27 23:40:14 【问题描述】:

我有一个绑定到分层数据模板的对象集合,我的每个对象都有一个特定类型的属性(我们称之为属性“A”)。这种类型因每个对象而异。

如果数据模板包含图像和一些文本,根据属性“A”的类型更改模板中显示的图像的最佳方法是什么。

我知道我可以将它粘贴到转换器中并在代码中手动进行绑定翻译,但是使用 WPF 中可用的所有绑定工具,我认为可能有更好的方法。

【问题讨论】:

【参考方案1】:

如果您创建本地数据模板并使用ContentPresenter,在您的数据模板中执行此操作非常简单。此模板呈现MyObject 类型的对象,显示一个图像,其来源由A 属性的类型确定,TextBlock 旁边显示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>

如果你想使用样式来代替,你会遇到问题,因为数据触发器想要查看属性值,以及A 属性的type本身并不作为属性公开。

当然,除非你实现一个:

public Type AType  get  return A.GetType();  

(当A 的值发生变化时,您还需要为AType 提高PropertyChanged。)完成此操作后,您应该能够以某种样式实现数据触发器,例如:

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

【讨论】:

【参考方案2】:

我认为您可以使用 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>

【讨论】:

如果我使用数据模板选择器,我不需要为每种类型的项目创建一个新模板吗? 是的。也许我误解了你想做什么。我编辑了我的答案。【参考方案3】:

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>

没测试过,不过思路是这样的。

【讨论】:

这似乎没有回答这个问题:“取决于属性的 type”。

以上是关于WPF DataTemplate 绑定取决于属性的类型的主要内容,如果未能解决你的问题,请参考以下文章

绑定到 DataTemplate 中的视图模型属性

WPF 绑定和动态分配 StringFormat 属性

WPF 菜单事件绑定 DataTemplate下button Command事件绑定 DataTemplate遍历实体数据

C#/WPF:获取 DataTemplate 中元素的绑定路径

wpf 模板选择器DataTemplateSelector及动态绑定使用教程

将 WPF 按钮 CommandParameter 绑定到 DataTemplate 中的按钮本身