0

I notice that the TabControl that has its ItemsSource property bound to an ObservableCollection正规365体育投注 does not select the first item in the collection if you do the following:

  1. Load TabControl when the ObservableCollection has a count of 0 (tab items are not showing)
  2. Add an item to the ObservableCollection, observe that one TabItem is now present but not selected

If you add an item to the ObservableCollection before the TabControl comes into focus for the first time, the one item in the TabControl has its TabItem selected. It only seems that when the tab count hits 0 then increases again does it seem to lose its ability to select the first item.

It seems this is by design. Is there any way to get around this issue?

I have the following tabcontrol definition in XAML as follows:

<TabControl ItemsSource="{Binding Sels}" />
| improve this question | | | | |
1

If you give the name tabControl to your TabControl正规365体育投注, then you could subscribe to the changes in its items collection in code-behind:

<TabControl ItemsSource="{Binding Sels}" x:Name="tabControl" />
tabControl.ItemContainerGenerator.ItemsChanged += ItemContainerGenerator_ItemsChanged;

and then you can force it to select the first tab if none are selected:

private async void ItemContainerGenerator_ItemsChanged(object sender, ItemsChangedEventArgs e) {
    await Task.Yield();
    if (tabControl.SelectedIndex == -1) {
        if (tabControl.Items.Count > 0) {
            tabControl.SelectedIndex = 0;
        }
    }
}

The call to await Task.Yield() is needed to let WPF finish handling internal TabControl updates before changing its SelectedIndex property.


To be extra fancy,

you could put this in an and in fine正规365体育投注 have a cleaner XAML and no extra code-behind:

<TabControl ItemsSource="{Binding Sels}" local:AutoSelect.AutoSelectFirstTab="true"/>

Here is the same behaviour but wrapped using WPF attached DependencyProperty:

public static class AutoSelect {
    public static readonly DependencyProperty AutoSelectFirstTabProperty = DependencyProperty.RegisterAttached(
        "AutoSelectFirstTab",
        typeof(bool),
        typeof(AutoSelect),
        new PropertyMetadata(false, AutoSelectFirstTabChanged));

    public static bool GetAutoSelectFirstTab(TabControl obj) => (bool)obj.GetValue(AutoSelectFirstTabProperty);
    public static void SetAutoSelectFirstTab(TabControl obj, bool value) => obj.SetValue(AutoSelectFirstTabProperty, value);

    private static void AutoSelectFirstTabChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
        var tabControl = (TabControl)d;
        tabControl.ItemContainerGenerator.ItemsChanged += ItemContainerGenerator_ItemsChanged;
        async void ItemContainerGenerator_ItemsChanged(object _1, ItemsChangedEventArgs _2) {
            await Task.Yield();
            if (GetAutoSelectFirstTab(tabControl)) {
                if (tabControl.SelectedIndex == -1) {
                    if (tabControl.Items.Count > 0) {
                        tabControl.SelectedIndex = 0;
                    }
                }
            }
        }
    }
}
| improve this answer | | | | |
  • 1
    Omg Corentin if I wasn't married I'd say something other than thank you!!!! You're a life saver :)! I was trying all sorts.. I got so depressed... I tried binding SelectedIndex to my VM (using MVVM and Caliburn Micro), and it didn't work... when I set it to 0 it would then automatically trigger and set it to 1 (there was no index 1 :( ). If I didn't touch it and it was at -1, then it wouldn't automatically update itself to go to 0. Was driving me mad... I even tried SelectedItem instead.. no luck.. Why it doesn't work with binding and works with a behaviour I won't know... – bobsyauncle yesterday

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy正规365体育投注

Not the answer you're looking for? Browse other questions tagged or ask your own question.