Pierre Toutant
Pierre Toutant

Reputation: 571

How to programmatically select a TabItem in WPF TabControl

I would like to know how to select a specific TabItem in a WPF TabControl.

I tried these bellow but nothing work!

MyTabControl.SelectedIndex = x

MyTabControl.SelectedItem = MyTabItem

MyTabControl.SelectedValue = MyTabItem

MyTabItem.IsSelected = True

Upvotes: 57

Views: 81544

Answers (9)

Alex
Alex

Reputation: 903

I'm throwing my 2 cents on the topic, since it might help someone out. I'm using WPF with Prims framework.

I was unable to select a tab by binding to SelectedItem or SelectedIndex - it didn't work. I was also unable to set TabItem.Name value from within TabControl.ItemTemplate or TabControl.ContentTemplate.

Instead I implemented event-based solution:

  1. Add Name value for my TabControl.
  2. Create an event - in Prism that means define a class that derives from PubSubEvent<T> (T is the type of parameter - in my case that was the ViewModel object bound to the TabItem>.
  3. Publish that event whenever I want to a tab to be selected.
  4. Subscribe to the event within my View.cs class and set the TabControl.SelectedItem programmatically using FindName.

Upvotes: 0

GreyCloud
GreyCloud

Reputation: 3100

if you don't know the index of the tab (hint its not TabIndex) use:

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

or modify it to search by name if you don't want to keep a reference to the tab

Upvotes: 0

Shanjee
Shanjee

Reputation: 519

I have implemented a small MVVM bindings based solution for selecting tab panels pragmatically.

  1. define a property in your view model - Selected int type

  2. bind the property in your view

    <TabControl
        x:Name="TabsCandidate" 
        VerticalAlignment="Stretch" 
        TabStripPlacement="Top"
        SelectedIndex="{Binding Selected}"
    
  3. private int _selected;

    public int Selected
    {
        get { return _selected; }
        set
        {
            _selected = value;
            OnPropertyChanged("Selected");
        }
    }
    
  4. Set the value to Select property, simply the binding will activate the tab panel.

    if you want to navigate from tab panel inside parent tab panels, this solution will simply works, All you need to do is, access the data context of your control and set it

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

Upvotes: 9

HCL
HCL

Reputation: 36795

All your examples except the third one are correct and will work. The problem must be at another location. Maybe you reset the item after setting or your code never is called?

Valid

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

Invalid

MyTabControl.SelectedValue = MyTabItem 

Upvotes: 34

Adrian Ratnapala
Adrian Ratnapala

Reputation: 5723

As @Chris says, any of the first three things should work and as @Phyxx says, it doesn't always really work. The problem is some subtle thing about the order of property changes. To work around it you need to let the WPF invoke your tab-selection code in its own time:

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

This does just what Phyxx' timer does, but in a slightly less extreme way.

Upvotes: 64

Phyxx
Phyxx

Reputation: 16108

I tried all the methods that should have worked, but like you nothing actually changed the selected tab. In the end I got it to work by putting the tab selection code in a DispatcherTimer tick.

       DispatcherTimer switchTabTimer = new DispatcherTimer();
       switchTabTimer.Interval = new TimeSpan(0);
       switchTabTimer.Tick += (object timerSender, EventArgs timerE) =>
       {
           myTabControl.SelectedIndex = 0;
           switchTabTimer.Stop();
       };
       switchTabTimer.Start(); 

Upvotes: 2

user2976441
user2976441

Reputation: 151

One thing which hasn't been mentioned above:

The main reason something like this won't work is that the tab items do not have the "Name" property set. Each tab item of the tab control which you want to navigate to programmatically must have its name property set for any of the above code to work.

<tabItem Name="tab1"></tabItem>

Upvotes: 15

kishhr
kishhr

Reputation: 191

Loop through the TabItems and for the tab to be selected, set

tabItem.IsSelected = true

If there are any other place due to binding changing you will see problem. Otherwise, the above code should work.

Upvotes: 17

Debasis
Debasis

Reputation: 458

Try to set the MyTabControl.SelectedIndex = x in the event handler of DataContextChanged or Loaded of your UI. Hope this will work.

Upvotes: 1

Related Questions