Search code examples
wpftriggersdatatemplate

WPF TabItem OnMouseOver shall trigger the visibility of a Button inside the TabItem


I have a TabControl containing TabItems. I overwrote their ItemTemplate to contain:

  • A TextBlock showing the caption of the TabItem
  • A Button (X) which closes the tab

Now I would like to make the "X"-Button only visible, when the TabItem is either selected or the mouse is over it.

This is my XAML code so far...

<TabControl x:Name="tabControl" 
                    ItemsSource="{Binding OpenedItems}">
            <TabControl.ItemTemplate>
                <DataTemplate>
                    <Grid Name="grid" VerticalAlignment="Center">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="Auto" />
                        </Grid.ColumnDefinitions>
                        <TextBlock Text="{Binding TabCaption}"  
                                   Grid.Column="0"
                                   Foreground="White"
                                   HorizontalAlignment="Left" 
                                   Margin="3" 
                                   Name="label_TabTitle" 
                                   VerticalAlignment="Center" />
                        <Button Content="X"  
                                Grid.Column="1"
                                Foreground="White"
                                HorizontalAlignment="Right" 
                                Margin="3" 
                                Name="button_close" 
                                VerticalAlignment="Center" 
                                Width="20" 
                                Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" 
                                Visibility="Hidden" 
                                Click="button_close_Click_1">
                        </Button>
                    </Grid>

                    <DataTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True" >
                            <Setter TargetName="button_close" Property="Visibility" Value="Visible"/>
                        </Trigger>
                    </DataTemplate.Triggers>
                </DataTemplate>
            </TabControl.ItemTemplate>
            <TabControl.ItemContainerStyle>
                <Style TargetType="TabItem">
                    <Setter Property="Background" Value="#1C1C1C" />
                    <Setter Property="Content" Value="{Binding TabContentView}"/>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type TabItem}">
                                <Grid Name="Grid"
                              Background="{StaticResource GrayBrush}">
                                    <ContentPresenter x:Name="ContentSite"
                                                  VerticalAlignment="Center"
                                                  HorizontalAlignment="Center"
                                                  ContentSource="Header"
                                                  RecognizesAccessKey="True">
                                    </ContentPresenter>
                                </Grid>
                                <ControlTemplate.Triggers>
                                    <Trigger Property="IsSelected" Value="True">
                                        <Setter TargetName="Grid" Property="Background" Value="{StaticResource BlueBrush}" />
                                    </Trigger>
                                    <Trigger Property="IsMouseOver" Value="True">
                                        <Setter TargetName="Grid" Property="Background" Value="{StaticResource LightBlueBrush}" />
                                    </Trigger>
                                </ControlTemplate.Triggers>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </TabControl.ItemContainerStyle>
        </TabControl>

With the Trigger inside the DataTemplate it kind of works.. but: you have to hover the mouse directly over the Label in order to show the button. So basically, it is impossible to click the button, because it disappears again.

I would appreciate any help with these WPF Templates!

Thanks, Christian


Solution

  • It looks as though your TabItem does not have the background set so it is not catching the MouseOverEvent. Since the TextBlock has the foreground set and has text, it captures the MouseOverEvent. Try setting the Background child grid of the DataTemplate to Transparent and you should see that the MouseOverEvent will be caught and show the close button.

    <TabControl x:Name="tabControl" ItemsSource="{Binding OpenedItems}">
        <TabControl.ItemTemplate>
            <DataTemplate>
                 <Grid Name="grid" VerticalAlignment="Center" Background="Transparent">
                    ...
                 </Grid>
                 ...
            </DataTemplate>
        </TabControl.ItemTemplate>
        ...
     </TabControl>