Вопрос по wpf, tabitem, tabcontrol – Как программно выбрать TabItem в WPF TabControl

31

Я хотел бы знать, как выбрать определенный TabItem в WPF TabControl.

Я попробовал эти ниже, но ничего не работает!

MyTabControl.SelectedIndex = x

MyTabControl.SelectedItem = MyTabItem

MyTabControl.SelectedValue = MyTabItem

MyTabItem.IsSelected = True

Ваш Ответ

8   ответов
36

любая из первых трех вещейдолжен работать и, как говорит @Phyxx, это не всегда действительно работает. Проблема заключается в некоторой тонкой вещи в порядке изменения свойств. Чтобы обойти это, вы должны позволить WPF вызывать ваш код выбора вкладок в свое время:

Dispatcher.BeginInvoke((Action)(() => MyTabControl.SelectedIndex = x));

Это делает только то, что делает таймер Phyxx, но немного менее экстремально.

@Digifaktur, это тоже почти успокаивает мои нервы. Я был слишком резок в Microsoft; Каркасы GUI сложны, потому что все потенциально получают уведомления обо всем остальном, в порядке «кто знает, что». Я в порядке сDispatcher.*Invoke за шунтирование кода между потоками, но я нервничаю, когда мне приходится слепо использовать его в одном потоке только потому, что я не понимаю, что происходит. Adrian Ratnapala
Если это успокаивает ваши нервы - совершенно нормально вызывать диспетчера для некоторых действий пользовательского интерфейса WPF, на самом деле это лучший способ убедиться, что это происходит в нужное время, в правильной среде. Это особенно актуально для многопоточных приложений или при использовании задач. Ответ Адриана должен быть помечен как «ответ» - он самый правильный. Digifaktur
Хорошие моменты / обсуждение вокруг, +1. Мне не нравится идеяDispatcherлибо, что похоже на переход к другому пути инструкций, когда он должен просто иметь возможность выполнять ту же инструкцию в основной строке. Но это возможно, как сказал Адриан - его вызывают слишком рано, и более поздние команды перезаписывают его - он вызывается слишком поздно, и получатель не знает, что делать. Похоже, плохой дизайн со стороны MS, чтобы иметь такое разъединение, но думаю, это то, что мы застряли. vapcguy
Мое предположение: MS развивается неправильно, но не "нагло". WPF - сложный и нечеткий API, и, похоже, не существует «одного правильного способа» его использования. В результате вы непременно создадите ситуацию, которую MS не проверяла на ожидаемость и не защищала от нее. В этом случае мы как-то устанавливаем поле либо слишком поздно (чтобы оно игнорировалось), либо слишком рано (чтобы оно перезаписывалось). Никто, даже Microsoft, не знает, что сейчас самое подходящее время. Adrian Ratnapala
НоПочему это так? Предложение сработало замечательно (+1), но я не могу перестать бояться, что, делая это таким образом, скрывает только что скрытую проблему. Когда я выбирал между тем, что я делаю что-то явно не так, и разработчиком Microsoft, который делал что-то явно неправильно, я выбирал самую безопасную лошадь - меня. Konrad Viltersten
13

Перейдите к элементам TabItems и для выбранной вкладки установите

tabItem.IsSelected = true

Если есть другие места из-за изменения привязки, вы увидите проблему. В противном случае приведенный выше код должен работать.

Ага. Это помогло мне. Это должен быть правильный ответ. Mosquito Mike
Лучший ответ на сегодняшний день! Andreas
1

MyTabControl.SelectedIndex = x в обработчике событийDataContextChanged или жеLoaded вашего интерфейса. Надеюсь, это сработает.

0

если вы не знаете индекс вкладки (подсказкане TabIndex) использовать:

    private async Task ChangeTabTo(TabItem wantedTab) {
        int index = 0;
        for (var i = 0; i < TabControl.Items.Count; i++) {
            var tab = TabControl.Items[i];
            var t = tab as TabItem;
            if (t == null) continue;
            if (t == wantedTab) {
                index = i;
                break;
            }
        }

        await Dispatcher.BeginInvoke((Action)(() => TabControl.SelectedIndex = index));
    }

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

11

Основная причина, по которой это не сработает, заключается в том, что для элементов вкладки не установлено свойство «Имя». Каждый элемент вкладки элемента управления вкладки, к которому вы хотите перейти программно, должен иметь свое свойство name, установленное для работы любого из приведенного выше кода.

<tabItem Name="tab1"></tabItem>
Это сработало для меня. На динамически создаваемых вкладках не работал ни один из методов, которые должны работать. Я добавил им имена, и они начали работать, как и ожидалось. Craig Neil Brown
21

кроме третьего, верны и будут работать. Проблема должна быть в другом месте. Может быть, вы сбрасываете пункт после установки или ваш код никогда не вызывается?

действительный

MyTabControl.SelectedIndex = x   
MyTabControl.SelectedItem = MyTabItem    
MyTabItem.IsSelected = True 

Инвалид

MyTabControl.SelectedValue = MyTabItem 
1

которыедолжен сработало, но, как вы, на самом деле ничего не изменило выбранную вкладку В конце концов я заставил его работать, поместив код выбора вкладки вDispatcherTimer поставить галочку.

       DispatcherTimer switchTabTimer = new DispatcherTimer();
       switchTabTimer.Interval = new TimeSpan(0);
       switchTabTimer.Tick += (object timerSender, EventArgs timerE) =>
       {
           myTabControl.SelectedIndex = 0;
           switchTabTimer.Stop();
       };
       switchTabTimer.Start(); 
теперь это безобразно lahjaton_j
5

кого выбора вкладок.

определить свойство в вашей модели представления - Выбранный тип int

привязать недвижимость на ваш взгляд

<TabControl
    x:Name="TabsCandidate" 
    VerticalAlignment="Stretch" 
    TabStripPlacement="Top"
    SelectedIndex="{Binding Selected}"

private int _selected;

public int Selected
{
    get { return _selected; }
    set
    {
        _selected = value;
        OnPropertyChanged("Selected");
    }
}

Установите значениеВыбрать свойство, просто привязка активирует панель вкладок.

Если вы хотите перемещаться из панели вкладок внутри родительских панелей вкладок, это решение будет просто работать. Все, что вам нужно сделать, это получить доступ к контексту данных вашего элемента управления и установить его.

// set the property value of the view model which points the index of the tab controller.
((CandidateViewModel)((System.Windows.FrameworkElement)candidateTab.Content).DataContext).Selected = CandidateLogTabIndex;
Это позволило мне выбрать нужную вкладку, одновременно используя MVVM. AndyUK

Похожие вопросы