2013-06-12 2 views
2

У меня есть следующий код в моем XAML, который показывает TabControl и шаблоны, чтобы отобразить заголовок, содержимое и кнопку закрытия, чтобы закрыть вкладку. Но я хочу, чтобы контент был другим в зависимости от типа вкладки. т. е. тип модели представления. Сейчас он жестко закодирован для определенного вида. Ранее я использовал свойство Data Type в шаблоне данных. Но я не уверен, как использовать его в сочетании с селектором шаблонов.wpf как установить datatemplate на основе типа

<Window.Resources> 
    <DataTemplate x:Key="ClosableTabItemTemplate"> 
     <DockPanel Width="120"> 
      <Button 
       Command="{Binding ElementName=MainTabControl, Path=DataContext.RemoveTabCommand}" 
       CommandParameter="{Binding Path=DealName}" 
       Content="x" 
       Cursor="Hand" 
       DockPanel.Dock="Right" 
       Focusable="False" 
       FontFamily="Courier" 
       FontSize="9" 
       FontWeight="Bold"      
       Padding="0" 
       VerticalContentAlignment="Bottom" 
       Width="16" Height="16" 
      /> 

      <ContentControl 
       Content="{Binding Path=Header}"      
       VerticalAlignment="Center"> 

       <ContentControl.Style> 
        <Style> 
         <Style.Triggers> 
          <DataTrigger Binding="{Binding Path=Header}" Value="New Deal"> 
           <Setter Property="ContentControl.Foreground" Value="Blue"></Setter> 
          </DataTrigger> 
         </Style.Triggers> 
        </Style> 
       </ContentControl.Style> 
      </ContentControl>     
     </DockPanel> 
    </DataTemplate> 

    <DataTemplate x:Key="newTabButtonContentTemplate"> 
     <Grid/> 
    </DataTemplate> 

    <DataTemplate x:Key="newTabButtonHeaderTemplate"> 
     <Button Content="+" Width="20" Height="20" Command="{Binding ElementName=MainTabControl, Path=DataContext.NewTabCommand}"/> 
    </DataTemplate> 

    <DataTemplate x:Key="itemContentTemplate"> 
     <v:DealView/> 
    </DataTemplate> 

    <v:TemplateSelector x:Key="headerTemplateSelector" 
         NewButtonTemplate="{StaticResource newTabButtonHeaderTemplate}" 
         ItemTemplate="{StaticResource ClosableTabItemTemplate}"/> 

    <v:TemplateSelector x:Key="contentTemplateSelector" 
         NewButtonTemplate="{StaticResource newTabButtonContentTemplate}" 
         ItemTemplate="{StaticResource itemContentTemplate}"/> 
</Window.Resources> 

<Window.DataContext> 
    <vm:MainViewModel /> 
</Window.DataContext> 

<Grid> 
    <DockPanel> 
     <TabControl DockPanel.Dock="Bottom" x:Name="MainTabControl" Margin="2" ItemsSource="{Binding Tabs}" 
           IsSynchronizedWithCurrentItem="True"         
           ItemTemplateSelector="{StaticResource headerTemplateSelector}" 
           ContentTemplateSelector="{StaticResource contentTemplateSelector}"> 

      <TabControl.Resources> 
       <Style TargetType="{x:Type TabPanel}"> 
        <Setter Property="Background" Value="AliceBlue"/> 
       </Style>     
      </TabControl.Resources> 
     </TabControl> 
    </DockPanel> 
</Grid> 

Мой TemplateSelector класс является следующее:

public class TemplateSelector : DataTemplateSelector 
{ 
    public DataTemplate ItemTemplate { get; set; } 
    public DataTemplate NewButtonTemplate { get; set; } 

    public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
     if (item == CollectionView.NewItemPlaceholder) 
     { 
      return NewButtonTemplate; 
     } 
     else 
     { 
      return ItemTemplate; 
     } 
    } 
} 

Мои закладки представляет собой набор ViewModels:

public ObservableCollection<ViewModelBase> Tabs 
{ 
    get 
    { 
     if (tabs == null) 
     { 
      tabs = new ObservableCollection<ViewModelBase>(); 
      var itemsView = (IEditableCollectionView)CollectionViewSource.GetDefaultView(tabs); 
      itemsView.NewItemPlaceholderPosition = NewItemPlaceholderPosition.AtEnd; 
     } 

     return tabs; 
    } 
} 

Так что я хочу что-то подобное с моим шаблоном ItemContentTemplate данных:

<DataTemplate x:Key="itemContentTemplate"> 
    when type is DealViewModel use <v:DealView/> 
    when type is DealSummaryViewModel use <v:DealSummaryView/> 
    etc 
</DataTemplate> 

ответ

0

Ранее я использовал свойство Data Type в шаблоне данных. Но я не уверен, как использовать его в сочетании с селектором шаблонов.

Если вы просто упасть обратно на базу, как в:

return base.SelectTemplate(item, container); 

... вы должны получить поведение по умолчанию, т.е. выбрав шаблон с соответствующим DataType. Достаточно ли этого? (На самом деле, вы можете просто вернуть нулевой, так как это все, что он делает.)

Другой вариант доступа к ключам ресурсов из селектора:

return ((FrameworkElement)container).FindResource(resourceKey) as DataTemplate; 

где resourceKey вычисляется на основании пункта и шаблона с этим ключом определяется где-то выше дерева, чем контейнер.

+0

Как бы изменился синтаксис? Прямо сейчас у меня есть ItemTemplate = "{StaticResource itemContentTemplate}" /> и соответствующий шаблон данных для этого . Как это изменится? – Satfactor

+0

Измените свойство 'ItemTemplate' из вашего селектора и замените' x: Key' на 'DataType =" {x: Тип vm: DealViewModel} "' (или оставьте «x: Key» там и создайте селектор для особого поиска вверх по соответствующему ключу). – nmclean

+0

Снятие свойства itemtemplate работало !!. Пока неясно, как это. Но спасибо.... – Satfactor

Смежные вопросы