简体   繁体   English

WPF如何根据类型设置数据模板

[英]wpf how to set datatemplate based on type

I have the following code in my XAML which shows a TabControl and templates to show the header, content and close button to close the tab. 我的XAML有以下代码,其中显示了TabControl和模板,以显示标题,内容和关闭按钮以关闭选项卡。 But I want the content to be different based on the type of tab. 但是我希望内容根据选项卡的类型而有所不同。 ie the type of the view model. 即视图模型的类型。 Right now it is hard coded to a specific view. 现在,它已硬编码到特定视图。 I have previously used the Data Type property in the data template. 我以前在数据模板中使用过数据类型属性。 But I am not sure how to use it in combination with the template selector. 但是我不确定如何将其与模板选择器结合使用。

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

My TemplateSelector class is the following: 我的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;
        }
    }
}

My tabs is a collection of ViewModels : 我的标签是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;
     }
 }

So I want something like this with my ItemContentTemplate data template: 所以我想要这样的东西与我的ItemContentTemplate数据模板:

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

I have previously used the Data Type property in the data template. 我以前在数据模板中使用过数据类型属性。 But I am not sure how to use it in combination with the template selector. 但是我不确定如何将其与模板选择器结合使用。

If you just fall back to the base, as in: 如果您只是跌倒了基地,例如:

return base.SelectTemplate(item, container);

...you should get the default behavior, ie selecting the template with a matching DataType . ...您应该获得默认行为,即选择具有匹配DataType的模板。 Would that be sufficient? 这样就足够了吗? (Actually, you can just return null, since that's all it does.) (实际上,您可以只返回null,因为这就是它的全部功能。)

Another option is to access resource keys from the selector: 另一个选择是从选择器访问资源密钥:

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

where resourceKey is computed based on the item, and a template with that key is defined somewhere higher up the tree than the container. 其中resourceKey是根据项目计算的,并且具有该键的模板在树上比容器更高的位置定义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM