question

JasonEtherton-2032 avatar image
0 Votes"
JasonEtherton-2032 asked EmonHaque-1485 edited

How do I prevent a child TabControl from inheriting the parent TabControl's SelectionChanged event handler?

Hello World,

I'm fairly new to WPF and am trying to embed a TabControl within another TabControl. My issue is that the child TC (with NO SelectionChanged handler defined) is triggering the parent's SelectionChanged handler.

I don't care about the child's TabControl selection, and although I could just add in a new handler for the child with e.handled = true, this seems like a workaround (albeit small) for inherited behaviour that I neither configured nor wanted.

Am I missing something?

I can't set SelectionChanged="" or SelectionChanged="null" - Is there a "proper" way to avoid event handler inheritance in XAML?

Using the snippets below, the parent's handler is triggered by changing the child tab selection.

XAML:

 <TabControl Name="ParentTab" SelectionChanged="ParentTabSelectionChangedHandler">
     <TabItem Header="TabItem1" />
     <TabItem Header="TabItem2">
         <TabControl Name="ChildTab" TabStripPlacement="Left">
             <TabItem Header="TabItem3" />
             <TabItem Header="TabItem4" />
         </TabControl>
     </TabItem>
 </TabControl>

C#

 private void ParentTabSelectionChangedHandler(object sender, SelectionChangedEventArgs e)
 {
     Debug.Print("Sent from " + (sender as TabControl).Name);    
     e.Handled = true;
 }


In visual form

 MainWindow
 └─ ParentTab (ParentTabSelectionChangedHandler)
    ├─ TabItem1
    └─ TabItem2
       └─ ChildTab
          ├─ TabItem3
          └─ TabItem4

So switching between TabItem1 and TabItem2 triggers the event handler, as expected. Switching between TabItem3 and TabItem4 also triggers the child's inherited version of the parent's event handler. This is prevented from bubbling further by the e.handled = true line, but my issue is that the parent's tab selection does not change.

It just seems strange as this strategy forces any nested Selectors uninterested in the top level event to explicitly catch events just to ignore them. Depending upon the application, this could be many lines of code put in place explicitly to do nothing.

In the above example, selecting TabItem3 triggers ParentTabSelectionChangedHandler even though the parent TabControl (ParentTab) does not have its selection changed (it remains on TabItem2), and ChildTab has no SelectionChanged event handler defined.

Please help, internet - the act of adding lines of code to ignore behaviour I haven't configured makes me think I'm doing something wrong.

windows-wpf
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

DaisyTian-1203 avatar image
0 Votes"
DaisyTian-1203 answered EmonHaque-1485 edited

Selector.SelectionChanged Event occurs when the selection of a Selector changes. The ChildTab is included in ParentTab Selector , ChildTab selectionChanged causes ParentTab to has a selectionChanged.
I make some update to your code and use MouseLeftButtonDown to replace selectionChanged. Below is my code for you:
XAML code:

 <TabControl>
             <TabControl.ItemContainerStyle>
                 <Style TargetType="TabItem" BasedOn="{StaticResource {x:Type TabItem}}">
                     <Setter Property="HeaderTemplate">
                         <Setter.Value>
                             <DataTemplate>
                                 <Label Content="{Binding}" Name="ParentTab">
                                     <Label.Style>
                                         <Style TargetType="Label">
                                             <EventSetter Event="MouseLeftButtonDown" Handler="Label_MouseLeftButtonDown"/>
                                         </Style>
                                     </Label.Style>
                                 </Label>
                             </DataTemplate>
                         </Setter.Value>
                     </Setter>
                 </Style>
             </TabControl.ItemContainerStyle>
             <TabItem Header="TabItem1" />
             <TabItem Header="TabItem2">
                 <TabControl Name="ChildTab" TabStripPlacement="Left">
                     <TabItem Header="TabItem3" />
                     <TabItem Header="TabItem4" />
                 </TabControl>
             </TabItem>
         </TabControl>

C# code is:

  private void Label_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
         {
             Debug.Print("\n ************ Sent from " + (sender as Label).Name);
         }

If the response is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

· 5
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

So the ChildTab (and any further children) SelectionChanged events need to be explicitly caught just to be ignored, with e.handled = true to prevent the event bubbling to the ParentTab SelectionChanged event handler?

0 Votes 0 ·
Viorel-1 avatar image Viorel-1 JasonEtherton-2032 ·

I think that you should add the handlers for controls that need them, and start the code by verifying the sender, for example: ‘if sender != myTab then return else do useful work’. You do not have to add handlers just to execute ‘e.handled = true’.

0 Votes 0 ·

I think that you should add the handlers for controls that need them

That's what I have done - the event handler is only specified for the ParentTab

start the code by verifying the sender, for example: ‘if sender != myTab then return else do useful work’

I shall implement this

You do not have to add handlers just to execute ‘e.handled = true’.

OK, so it is by design that child events do trigger the parent's event handler, which is why I need to check the sender is the one I am interested in?











0 Votes 0 ·
Show more comments