tags:

views:

149

answers:

2

The following example xaml causes each tab item to share the same TextBox. It makes sense, on some level I guess... but it's unexpected behavior, and almost feels like a bug. And I couldn't find any information in the docs explaining the behavior, or how to correctly get around it.

<TabControl>
    <TabControl.Resources>
        <Style TargetType="TabItem">
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <TextBox />
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </TabControl.Resources>
    <TabItem Name="tab1" />
    <TabItem Name="tab2" />
</TabControl>

When switching between tab1 and tab2, the same TextBox is used, when I would expect a new TextBox for each tab. How can I get the latter case?

Subclassing TabItem and making its content a TextBox by default is one way to do it, but I just want to be sure there isn't something I'm missing.

Edit

I realize that setting the content explicitly for each tab will solve the problem, but the tabs are to be created dynamically. I want to use the content template so that I may add new tabs via data binding and have the content unshared as it is causing quirky behavior.

Perhaps with the current implementation of the TabControl, there is no declarative approach to solving this. It's pretty trivial setting the content in code, but such things always feel wrong in WPF. To me, this seems like an unjustified optimization of the TabControl; it should at least be optional for situations where it is not practical.

+1  A: 

I suspect there's a nicer way to achieve whatever it is you're trying to achieve, but I think this will work (would test but I'm on linux atm):

<TabControl>
    <TabControl.Resources>
        <Style TargetType="TabItem" x:Shared="False">
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <TextBox />
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </TabControl.Resources>
    <TabItem Name="tab1" />
    <TabItem Name="tab2" />
</TabControl>

HTH,
Kent

Kent Boogaart
Ah, this looked promising... unfortunately, each time a tab is selected, its old content is overwritten with a new empty TextBox.
Siege
+1 anyway for making me aware of the "Shared" attribute :P
Siege
A: 

It will work if you define a usercontrol that has the tab content in it. I created the following usercontrol:

<UserControl x:Class="SO_Testing.TextBoxUC"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <TextBox/>
    </Grid>
</UserControl>

Then I modified my window xaml to be this:

<Window x:Class="SO_Testing.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:SO_Testing"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TabControl>
            <TabItem Name="tab1" Header="Test">
                <local:TextBoxUC/>
            </TabItem>
            <TabItem Name="tab2" Header="Test 2">
                <local:TextBoxUC/>
            </TabItem>
        </TabControl>
    </Grid>
</Window>

This may not be exactly what you are wanting, but at least the layout of each tab is only defined in one place and you can then assign a datacontext to each usercontrol to show the values for each of your tabs.

aalex675
This doesn't solve the problem I was illustrating. The UserControl here is also pointless, because if you specifically set the content as you did here it will work with a plain old TextBox; the problem is with the content template causing content to be shared among tabs whose content is not set explicitly. I did, however, try to use a UserControl in the template to see if it would make any difference but, as expected, it didn't.I updated my question to be more clear.
Siege