How to change selected tab on Button click in WPF TabControl with Buttons in Header

HiteshP picture HiteshP · Jul 2, 2009 · Viewed 28.5k times · Source

I have a WPF TabControl that has a couple of buttons in the TabItem header. I want the selected tab to change when a headered button is clicked. Here is a code snippet:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
   <Grid>
      <TabControl>
         <TabItem Content="Item 1 Content">
            <TabItem.Header>
               <StackPanel Orientation="Vertical">
                  <TextBlock FontSize="14" FontWeight="Bold" Text="Item1"/>
                  <StackPanel Orientation="Horizontal">
                     <Button Content="Action 1"/>
                     <Button Content="Action 2"/>
                  </StackPanel>
               </StackPanel>
            </TabItem.Header>
         </TabItem>
         <TabItem Content="Item 2 Content">
            <TabItem.Header>
               <StackPanel Orientation="Vertical">
                  <TextBlock FontSize="14" FontWeight="Bold" Text="Item2"/>
                  <StackPanel Orientation="Horizontal">
                     <Button Content="Action 1"/>
                     <Button Content="Action 2"/>
                  </StackPanel>
               </StackPanel>
            </TabItem.Header>
         </TabItem>
      </TabControl>
   </Grid>
</Page>

This sample show a couple of Tabs. A tab is selected if the header background is clicked, however, if a button is clicked the tab is not selected. I want the button to accept the click but I also want the tab corresponding to the button to get selected. Can anyone help?

Thanks, Hitesh

Answer

rmoore picture rmoore · Jul 2, 2009

We can do this by using Event Routing. RoutedEvents, such as Click will bubble up the element tree, until something handles the event. Because of this, you're actually already receiving the Click event on the tab items, we just aren't doing anything with it yet. We could create an event to handle the Button Click on the tab items like this:

<TabItem Content="Item 1 Content" ButtonBase.Click="TabItem_Click">

However, we'd have to set that on each tab, so instead we can create a style for the TabItems in the TabControl like so:

<TabControl>
    <TabControl.ItemContainerStyle>
        <Style TargetType="{x:Type TabItem}">
            <EventSetter Event="ButtonBase.Click"
                         Handler="TabItem_Click" />
        </Style>
    </TabControl.ItemContainerStyle>
....
</TabControl>

Now, in our event handler we can select the tab that has been clicked:

private void TabItem_Click(object sender, RoutedEventArgs e)
{
    Trace.WriteLine("TabItemClicked");
    ((TabItem)sender).IsSelected = true;
    e.Handled = true;
}