WPF TabControl - 无法以编程方式选择选项卡

时间:2011-05-25 17:25:59

标签: c# wpf tabcontrol

我有一个TabControl的用户界面,最初显示一个起始页面。可以通过双击(例如,DataGrid)中的内容将其他项添加到其中。创建新选项卡时应选择它们。如果与网格中的项目对应的文档已经打开,则应打开该文档的现有选项卡,而不是创建新文档。

我知道我应该能够通过设置TabControl的SelectedItem或SelectedIndex属性以编程方式选择选项卡。但是,所需的选项卡实际上从未激活。如果我设置了一个,然后在调试器中检查TabControl的状态,那么两个字段似乎都正确更新。但是,在我继续执行之后,我看到选定的选项卡在UI中保持不变,如果我暂停并再次检查TabControl的状态,我会看到SelectedItem和SelectedIndex已经返回到之前的值。另一方面,通过在UI中单击选项卡来选择选项卡可以正常工作。

这是TabControl的声明:

<TabControl x:Name="Tabs" >
    <TabItem x:Name="StartPageTab" Header="Start Page" DataContext="{Binding Path=StartPageViewModel}">
        ...
    </TabItem>
</TabControl>

添加和选择标签的代码:

private void _SelectTab(MyViewModel model)
{
    TabItem tab;
    if (_TryFindTab(model, out tab)) Tabs.SelectedItem = tab;
}

private bool _TryFindTab(MyViewModel target, out TabItem tab)
{
    foreach (TabItem item in Tabs.Items)
    {
        MyViewModel model = item.DataContext as MyViewModel;
        if (model != null && model.Equals(target))
        {
            tab = item;
            return true;
        }
    }
    tab = null;
    return false;
}

private void _AddTab(MyViewModel model)
{
    TabItem tab = new TabItem { DataContext = model, Content = new MyView() };
    Binding bind = new Binding { Source = model, Path = new PropertyPath("Name") };
    tab.SetBinding(TabItem.HeaderProperty, bind);

    Tabs.Items.Add(tab);
    Tabs.SelectedItem = tab;
}

4 个答案:

答案 0 :(得分:19)

事实证明这与我在原始问题描述中方便省略的内容有关:

有问题的DataGrid位于StartPageTab的内容中。我通过捕获其MouseDoubleClick事件来处理该DataGrid的双击,搜索可视树以查找双击的DataGridRow(如果有的话),然后引发最终将被主窗口捕获的事件,这将响应通过调用_SelectTab或_AddTab,取决于相关文档是否已经打开。

此时,调用堆栈将展开并返回到MouseDoubleClick事件处理程序。在那个处理程序中,我忘了将MouseButtonEventArgs的Handled属性设置为true。因此,WPF继续搜索其他人来处理该点击事件 - 并且它最终找到的元素会通过询问焦点来响应,这反过来意味着原始标签需要重新获得焦点。

添加e.Handled = true;会阻止整个混乱,因此新标签可以保持选中状态。

答案 1 :(得分:4)

您可以尝试使用tab.focus()

我的应用程序中有标签,这是让您选择的标签可见的快捷方式。

答案 2 :(得分:0)

您是否尝试过绑定到TabItem.IsSelected并在视图模型中更新它?

答案 3 :(得分:0)

在我使用旧的C#应用​​程序中,使用页面控件,我可以通过告诉选项卡控件对象选择选项卡来强制页面处于活动状态...

MyTabControlWithMultiplePages.SelectTab(PageIWantShown);