wpf如何根据类型设置datatemplate

时间:2013-06-12 21:59:01

标签: c# wpf mvvm

我的XAML中显示以下代码,其中显示TabControl和模板,以显示标题,内容和关闭按钮以关闭标签。但我希望内容根据选项卡的类型而有所不同。即视图模型的类型。现在它被硬编码到特定视图。我以前在数据模板中使用了数据类型属性。但我不确定如何将它与模板选择器结合使用。

<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>

1 个答案:

答案 0 :(得分:0)

  

我以前在数据模板中使用过数据类型属性。但我不是   确定如何将它与模板选择器结合使用。

如果你只是回到基地,如:

return base.SelectTemplate(item, container);

...您应该获得默认行为,即选择匹配DataType的模板。那就够了吗? (实际上,你可以只返回null,因为它就是这样。)

另一种选择是从选择器访问资源键:

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

其中resourceKey是根据项目计算的,带有该键的模板定义在树的上方而不是容器中。