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