根据项类型和视图选项切换ListBox ItemTemplate

时间:2011-02-08 14:29:59

标签: c# wpf listbox datatemplateselector

我目前正在WPF中实现一个列表框,它的项目有两个替代布局:

Alternative list item styles of wrapping icons and detailed tiles

到目前为止,我已使用DataTriggerItemTemplate切换ListBox,并且效果很好:

<ListBox ItemsSource="{Binding Runs}" SelectedItem="{Binding SelectedRun}">
  <ListBox.Style>
    <Style TargetType="ListBox">
      <Setter Property="ItemTemplate" Value="{StaticResource tileTemplate}"/>
      <Style.Triggers>
        <DataTrigger Binding="{Binding ShowRunsAsIcons}" Value="True">
          <Setter Property="ItemTemplate" Value="{StaticResource iconTemplate}"/>
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </ListBox.Style>
</ListBox>

但是,列表绑定到的Runs集合还将包含不同的类型对象:

interface IRunItem
{
  // ...
}

class CompletedRunItem : IRunItem
{
  // ...
}

class PendingRunItem : IRunItem
{
  // ...
}

每个对象类型都应该有自己的“tile”和“icon”模板(共计4个模板)。根据布尔ShowRunsAsIcons和列表项的类型,将这两个属性切换为最佳方法是什么?

我考虑过使用一对DataTemplateSelector子类 - 一个用于根据项目类型选择切片模板,另一个用于根据项目类型在图标模板之间进行选择 - 但这只是感觉非常笨重。我觉得我应该利用WPF根据对象的类型选择正确的模板的能力,但在这个例子中,我没有看到如何将它与列表的不同视图选项结合起来。

关于如何做到这一点的任何想法更符合WPF的精神?

感谢。

1 个答案:

答案 0 :(得分:1)

虽然我不相信这是最好的答案,但我已经改变了我的方法,以利用WPF的自动模板选择。我现在为每个具体数据类定义了“顶级”数据模板。

这些数据模板只包含ContentControl ContentTemplate属性,DataTrigger属性是通过PendingRunItem设置的,绑定到数据上下文的ShowRunsAsIcons属性。

例如,这是<DataTemplate DataType="{x:Type Common:PendingRunItem}"> <ContentControl Content="{Binding}"> <ContentControl.Style> <Style TargetType="ContentControl"> <Setter Property="ContentTemplate" Value="{StaticResource pendingTileTemplate}"/> <Style.Triggers> <DataTrigger Binding="{Binding DataContext.ShowRunsAsIcons, RelativeSource={RelativeSource FindAncestor, AncestorType=ListBox}}" Value="True"> <Setter Property="ContentTemplate" Value="{StaticResource pendingIconTemplate}"/> </DataTrigger> </Style.Triggers> </Style> </ContentControl.Style> </ContentControl> </DataTemplate> 的无密钥数据模板:

ListBox

相关类的图标和图块表示只是常规数据模板。并且Style不再需要定义<ListBox ItemsSource="{Binding Runs}" SelectedItem="{Binding SelectedRun}"/> 属性:

DataTemplateSelector

与使用{{1}}或者两个{{1}}相比,我有兴趣了解人们对这种方法及其优点和缺点的看法。