2011-02-08 1 views
2

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

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 коллекцию, в которой список привязан Wi будет также содержать разные типы объекта:

interface IRunItem 
{ 
    // ... 
} 

class CompletedRunItem : IRunItem 
{ 
    // ... 
} 

class PendingRunItem : IRunItem 
{ 
    // ... 
} 

Каждых из типов объектов, должны иметь свою собственную «плитку» и шаблоны «ICON» (изготовление 4 шаблонов в общей сложности). Каков наилучший способ включения этих двух свойств в соответствии с булевым ShowRunsAsIcons и типом элемента списка?

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

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

Спасибо.

ответ

1

Хотя я не уверен, что это лучший ответ, я изменил свой подход, чтобы воспользоваться автоматическим выбором шаблона 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 или два.