Переключение ListBox ItemTemplate на основе типа элемента и варианта просмотра - PullRequest
2 голосов
/ 08 февраля 2011

В настоящее время я реализую список в WPF, который будет иметь 2 альтернативных макета для своих элементов:

Alternative list item styles of wrapping icons and detailed tiles

До сих пор я делал это, используя DataTriggerпереключить ItemTemplate для 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, к которой привязан список, также будет содержать различные типы изobject:

interface IRunItem
{
  // ...
}

class CompletedRunItem : IRunItem
{
  // ...
}

class PendingRunItem : IRunItem
{
  // ...
}

Каждый из типов объектов должен иметь свои собственные шаблоны 'tile' и 'icon' (всего 4 шаблона).Как лучше всего включить эти два свойства в соответствии с логическим значением ShowRunsAsIcons и типом элемента списка?

Я рассмотрел возможность использования пары подклассов DataTemplateSelector - один из которых можно выбирать междушаблоны листов, основанные на типе элемента, и один на выбор между шаблонами значков, основанными на типе элемента, - но это кажется ужасно неуклюжим.Мне кажется, что я должен воспользоваться возможностью WPF выбирать правильный шаблон в зависимости от типа объекта, но в этом случае я не вижу, как совместить это с различными параметрами представления списка.

Любые идеи о том, как сделать это, больше в духе WPF?

Спасибо.

1 Ответ

1 голос
/ 08 февраля 2011

Хотя я не уверен, что это лучший ответ, я изменил свой подход, чтобы воспользоваться преимуществами автоматического выбора шаблонов WPF.Теперь у меня есть шаблоны данных «верхнего уровня», определенные для каждого из моих конкретных классов данных.

Эти шаблоны данных не содержат ничего, кроме ContentControl, свойство ContentTemplate которого устанавливается через DataTrigger, связывая ссвойство 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 илидва.

...