Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

wpf - Using a datatemplate for the TabItems in a tabControl

If I have a class called: GuiObject, and that class has a list of GuiObjects called: "GuiObjects".

Now say my window has a list of GuiObjects, which I use in the .xaml file to dataBind to:

<StackPanel>
    <ItemsControl ItemsSource="{Binding TopObjectList}" DataTemplateSelector="{DynamicResource templateSelector"/> 
</StackPanel>

I can make a datatemplate for every type of FrameworkElement I want to generate, but I'm having trouble with the TabControl. I can create a datatemplate for the tabControl like so:

<DataTemplate x:key="TabControlTemplate" DataTemplateSelector="{DynamicResource templateSelector" >
    <TabControl ItemsSource="{Binding GuiObjects}" />
</DataTemplate>

And the result is a tab control that has each of the proper pages present, but without the contents of the individual TabItems. Fair enough, I'll just make a DataTemplate for the TabItems. For each TabItem, I'd like to put the contents of GuiObjects into a stackpanel.

<DataTemplate x:key="TabItemTemplate" DataTemplateSelector="{Resource templateSelector">
    <TabItem Header = {Binding Title}>
        <StackPanel>
            <ItemsControl ItemsSource="{Binding GuiObjects}" DataTemplateSelector="{DynamicResource templateSelector"/> 
        </StackPanel>
    </TabItem>
</DataTemplate>

The problem here is that the TabItemTemplate never gets called. I've tried solutions that involve setting the ItemContainerStyle within the TabControlTemplate, but then I've got the problem of hierarchy. If I bind "GuiObjects" inside the content of the TabItem, I'm binding the list of tabItems, instead of the list that's within each TabItem. (I want to do the second one). Here's an example:

<DataTemplate x:key="TabControlTemplate" DataTemplateSelector="{DynamicResource templateSelector" >
    <TabControl ItemsSource="{Binding GuiObjects}">
        <TabControl.ItemContainerStyle>
            <Style TargetType="TabItem">
                <Setter Property="Header" Value="{Binding Title}"/>
                <Setter Property="Content" Value="<StackPanel><ItemsControl ItemsSource="{Binding GuiObjects}" DataTemplateSelector="{DynamicResource templateSelector"/></StackPanel>"/>
            </Style>
        </TabControl.ItemContainerStyle>
    </TabControl>
</DataTemplate>

Again, this solution has the levels problem: When I say: {Binding GuiObjets} I'm referring to the list of TabItems, instead of to the list of FrameworkElements within each TabItem.

The solution is either to stick with separate DataTemplates for both the TabControl and the TabItem, and just fix it so that the DataTemplateSelector actually works for the TabItems (no idea how to do this). Or to go with the ItemContainerStyle, and somehow tell it to go down one level when binding GuiObjects. Anyone know how to do this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

To provide a template for the contents of the pages of a TabControl, use the following properties:

The ItemTemplate/ItemTemplateSelector properties of a TabControl are used to define what the tab headers look like.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...