Search code examples
wpfeventstabcontroltabitem

WPF: Can not select first TabItem in TabControl with nested TabControls


I'm facing a strange issue with nested TabControls in WPF.

In my Home Window I need to put a TabControl inside another TabItem, in order to create different menu levels. Since I need to have no default-selected TabItem, I'm using TabControl.Loaded event like so:

    private void TabControl_Loaded(object sender, RoutedEventArgs e)
    {
        ((TabControl)sender).SelectedItem = null;
    }

The issue is: first TabItem of nested TabControl is not selectable, unless selecting the second one then clicking again on the first header.

I created a sample project to demonstrate the problem.

XAML:

<Window x:Class="TabControlTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TabControlTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <TabControl Loaded="TabControl_Loaded">
            <TabItem>
                <TabItem.Header>
                    <Label Content="Menu 1" />
                </TabItem.Header>
                <Grid>
                    <TabControl Loaded="TabControl_Loaded">
                        <TabItem>
                            <TabItem.Header>
                                <Label Content="Sub-Menu 1" />
                            </TabItem.Header>
                            <Grid>
                                <Button Content="Button in subitem 1" Margin="82,131,553,89" />
                            </Grid>
                        </TabItem>
                        <TabItem>
                            <TabItem.Header>
                                <Label Content="Sub-Menu 2" />
                            </TabItem.Header>
                            <Grid>
                                <Button Content="Button in subitem 2" Margin="429,69,206,151" />
                            </Grid>
                        </TabItem>
                    </TabControl>
                </Grid>
            </TabItem>
            <TabItem>
                <TabItem.Header>
                    <Label Content="Menu 2" />
                </TabItem.Header>
                <Grid>
                    <Button Content="Button in Hello 2" Height="NaN" Margin="274,65,54,237" Width="NaN" />
                </Grid>
            </TabItem>
        </TabControl>
    </Grid>
</Window>

If I disable the Loaded event, there are no issues.

Any help would be appreciated.

EDIT: I uploaded the sample project here.


Solution

  • Instead of handling the Loaded event, I believe you can add an invisible TabItem to prevent the first "real" tab from being selected initially:

    <TabControl>
        <TabItem Visibility="Collapsed" />
        <TabItem>
            <TabItem.Header>
                <Label Content="Menu 1" />
            </TabItem.Header>
            <Grid>
                <TabControl>
                    <TabItem Header="" Visibility="Collapsed" />
                    <TabItem>
                        <TabItem.Header>
                            <Label Content="Sub-Menu 1" />
                        </TabItem.Header>
                        <Grid>
                            <Button Content="Button in subitem 1" Margin="82,131,553,89" />
                        </Grid>
                    </TabItem>
                    <TabItem>
                        <TabItem.Header>
                            <Label Content="Sub-Menu 2" />
                        </TabItem.Header>
                        <Grid>
                            <Button Content="Button in subitem 2" Margin="429,69,206,151" />
                        </Grid>
                    </TabItem>
                </TabControl>
            </Grid>
        </TabItem>
        <TabItem>
            <TabItem.Header>
                <Label Content="Menu 2" />
            </TabItem.Header>
            <Grid>
                <Button Content="Button in Hello 2" Height="NaN" Margin="274,65,54,237" Width="NaN" />
            </Grid>
        </TabItem>
    </TabControl>
    

    Another potential workaround would be to bind the TabControl to a source collection using the ItemsSource property.