Как убедиться, что мой WPF TabControl всегда имеет выбранную вкладку, когда она содержит хотя бы одну вкладку?

У меня есть TabControl, элементы которого привязаны к ObservableCollection:

<TabControl ItemsSource="{Binding MyObservableCollection}" />

Вкладки добавляются и удаляются так, как ожидалось, поскольку элементы добавляются и удаляются из коллекции. Тем не менее, SelectedItem возвращается к -1 (что означает, что выбранная вкладка отсутствует) всякий раз, когда коллекция пуста. Затем, когда элемент добавлен, SelectedItem остается в -1, а новая вкладка не выбрана.

Как сделать TabControl выбрать новую вкладку всякий раз, когда элемент добавляется в пустую коллекцию?

Ответ 1

Возможно, будет более простой способ, но вы можете связать событие с изменением коллекции в ObservableCollection в своей виртуальной машине и установить для свойства SelectedItem новый элемент (при условии, что выбранный элемент привязан к свойству на виртуальной машине).

Ответ 2

Что вы можете сделать, так это подписаться на событие TabControl.ItemContainerGenerator.StatusChanged, и если статус ContainersGenerated и SelectedIndex из TabControl равен -1, то для создания SelectedIndex из TabControl 0;

// peopleCollection is an ObservableCollection<Person>
People peopleCollection = new People();
public Window1()
{
    InitializeComponent();
    // MyTabControl is an instance of TabControl
    MyTabControl.ItemsSource = peopleCollection;
    MyTabControl.ItemContainerGenerator.StatusChanged += new EventHandler(ItemContainerGenerator_StatusChanged);
}

void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)
{
    if((sender as ItemContainerGenerator).Status == System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated && MyTabControl.SelectedIndex == -1)
    {
        MyTabControl.SelectedIndex = 0; 
    }
}

Есть 3-сторонние партийные решения, которые имеют эту функциональность из коробки. Telerik RadTabControl выбирает первый элемент, когда коллекция меняет свое состояние с пустого на "содержащий один элемент".

Попробуйте демонстрацию здесь: http://demos.telerik.com/silverlight/#TabControl/AddingAndRemovingTabs

Примечание. Это демонстрация SL, но она работает одинаково в WPF.

Ответ 3

Если вы ищете чистую реализацию MVVM, добавьте свойство Index в ViewModel, а в CollectionChanged вы можете установить Index = 0, если внутри нет элементов. И в XAML вы можете связать этот индекс ниже

<TabControl ItemsSource="{Binding MyObservableCollection}" SelectedIndex="{Binding Index}" />

Ответ 4

лучше всего переписать функцию "OnTabAdded", чтобы проверить, добавлен ли новый (первый), а затем установить значение SelectedItemIndex равным 0;

поскольку вы используете ObservableCollection, вы знаете, когда меняется ваша коллекция, поэтому я подписался на измененную форму формы коллекции и проверил количество элементов в ней.

Ответ 5

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

<TabControl ItemsSource="{Binding MyObservableCollection}" SelectedItem="{Binding MyObservableCollection.First}" />

Работал для меня:)

Ответ 6

<TabControl ItemsSource="{Binding MyObservableCollection}" SelectedItem="{Binding MyObservableCollection[0]}" />