WPF:无法使用嵌套的 TabControls 选择 TabControl 中的第一个 TabItem

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

提问人:IFrank 提问时间:2/1/2023 最后编辑:IFrank 更新时间:2/2/2023 访问量:45

问:

我在WPF中遇到嵌套TabControls的一个奇怪问题。

在我的主窗口中,我需要将一个 TabControl 放在另一个 TabItem 中,以便创建不同的菜单级别。 由于我不需要默认选择的 TabItem,因此我使用如下事件:TabControl.Loaded

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

问题是:嵌套 TabControl 的第一个 TabItem 不可选择,除非选择第二个,然后再次单击第一个标题。

我创建了一个示例项目来演示该问题。

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>

如果我禁用该事件,则没有问题。Loaded

任何帮助将不胜感激。

编辑:我在这里上传了示例项目。

WPF 事件 控件 选项卡项

评论


答:

1赞 mm8 2/1/2023 #1

我相信您可以添加一个不可见的选项卡,而不是处理事件,以防止最初选择第一个“真实”选项卡:LoadedTabItem

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

另一种可能的解决方法是使用该属性将 绑定到源集合。TabControlItemsSource

评论

0赞 IFrank 2/2/2023
不错的解决方法!我真的很想知道为什么会这样。我注意到,如果我单击第一个选项卡(不起作用),然后停用并重新激活窗口,则最终选择了该选项卡。我想知道这是否可能是 WPF 级别的问题或类似问题。添加一个空的折叠 TabItem 完全解决了我的问题。
1赞 Andy 2/1/2023 #2

您可以处理 window.contentrendered,并在外部选项卡控件上将 selectedindex 设置为 -1:

    private void Window_ContentRendered(object sender, EventArgs e)
    {
        tc.SelectedIndex = -1;
    }

显然,我将该选项卡命名为 tc:

<Grid>
    <TabControl x:Name="tc">
        <TabItem>

当我在外部选项卡控件上处理加载时,同样的方法也有效。

    private void tc_Loaded(object sender, RoutedEventArgs e)
    {
        tc.SelectedIndex = -1;
    }

评论

0赞 IFrank 2/2/2023
谢谢你提供这个解决方案。它可以工作,但我注意到窗口激活和选项卡取消选择之间有一点延迟,尤其是在低规格的机器上。