WPF TabControl - не может программно выбирать вкладки

У меня есть пользовательский интерфейс с TabControl, который первоначально отображает стартовую страницу. Другие предметы могут быть добавлены к нему двойным щелчком по контенту, например, в DataGrid. При их создании следует выбирать новые вкладки. Если документ, соответствующий элементу в сетке, уже открыт, тогда существующую вкладку для этого документа следует открыть, а не создавать новую.

Я знаю, что я должен иметь возможность программно выбирать вкладку, задав свойства TabControl SelectedItem или SelectedIndex. Однако желаемая вкладка никогда не активируется. Если я установил один, а затем проверил состояние TabControl в отладчике, то оба поля, похоже, будут правильно обновляться. Однако после продолжения выполнения я вижу, что выбранная вкладка остается неизменной в пользовательском интерфейсе, и если я снова приостанавливаю и проверяю состояние TabControl, я вижу, что SelectedItem и SelectedIndex вернулись к своим предыдущим значениям. С другой стороны, выбор вкладки, щелкнув ее в пользовательском интерфейсе, отлично работает.

Здесь объявление для 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;
}

Ответ 1

Оказалось, что это связано с тем, что я просто пропустил из исходного описания проблемы:

Соответствующий DataGrid находился в содержимом для StartPageTab. Я обрабатывал двойные щелчки на этом DataGrid, захватывая его событие MouseDoubleClick, и искал визуальное дерево, чтобы найти, что DataGridRow был дважды щелкнул (если есть), а затем поднял событие, которое в конечном итоге будет захвачено главным окном, которое ответит вызывая либо _SelectTab, либо _AddTab, в зависимости от того, был ли этот документ уже открыт.

В этот момент стек вызовов разворачивается и возвращается к этому обработчику событий MouseDoubleClick. В этом обработчике я забыл установить для свойства MouseButtonEventArgs Handled значение true. Таким образом, WPF продолжал искать кого-то другого для обработки этого события клика - и элемент, который он в конечном итоге нашел, ответил бы, запросив фокус, что, в свою очередь, означало, что исходная вкладка должна была вернуть фокус.

Добавление e.Handled = true; остановило весь беспорядок на своих дорожках, поэтому новая вкладка может остаться выбранной.

Ответ 2

Вы можете попробовать использовать tab.focus()

У меня есть вкладки в моем приложении, и это быстрый способ сделать вашу выбранную вкладку видимой.

Ответ 3

Вы пытались привязаться к TabItem.IsSelected и обновляете это в своей модели?

Ответ 4

В более старом приложении С#, которое у меня было, с помощью элементов управления страницами, я смог принудительно активировать страницу, сообщив объекту управления вкладками, чтобы выбрать вкладку...

MyTabControlWithMultiplePages.SelectTab(PageIWantShown);