2

我目前正在 WPF 中实现一个列表框,它将为其项目提供 2 种替代布局:

包装图标和详细图块的替代列表项样式

到目前为止,我已经使用 aDataTrigger来切换ItemTemplateforListBox并且运行良好:

<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
{
  // ...
}

每个对象类型都应该有自己的“平铺”和“图标”模板(总共制作 4 个模板)。根据布尔值ShowRunsAsIcons和列表项的类型切换这两个属性的最佳方法是什么?

我考虑过使用一对子DataTemplateSelector类——一个根据项目类型在图块模板之间进行选择,一个根据项目类型在图标模板之间进行选择——但这感觉非常笨拙。我觉得我应该利用 WPF 根据对象类型选择正确模板的能力,但在这种情况下,我不知道如何将它与列表的不同视图选项结合起来。

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

谢谢。

4

1 回答 1

1

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

这些数据模板只包含 a ContentControl,其ContentTemplate属性通过 aDataTrigger绑定到数据上下文的 ShowRunsAsIcons 属性来设置。

例如,以下是无密钥数据模板PendingRunItem

<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两种方法相比的优缺点。

于 2011-02-08T17:36:03.427 回答