admin管理员组

文章数量:1391960

I've the following TabControl:

<TabControl  ItemsSource="{Binding Days}" Grid.Row="1" Margin="6" SelectedIndex="0" Loaded="OnTabLoaded">
    <TabControl.ItemContainerStyle>
        <Style TargetType="{x:Type TabItem}">
            <Setter Property="Header"  >
                <Setter.Value>
                    <Binding Path="Key" ConverterParameter="{}{0:ddd dd.MM}">
                        <Binding.Converter>
                            <converters:ToStringConverter></converters:ToStringConverter>
                        </Binding.Converter>

                    </Binding>
                </Setter.Value>
            </Setter>
            <Setter Property="Background" Value="IndianRed"></Setter>
            <Style.Triggers>
                <DataTrigger Binding="{Binding Value.HasError}" Value="False">
                    <Setter Property="Background" Value="LightGreen"></Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TabControl.ItemContainerStyle>
    
    <!-- Content -->
    
</TabControl>

Which basically set my tab header in specific color depending of the status of its content. But when I select a tab, the header is grey again.

How can I either keep the originally set color, either change the color of the tab based (again) on the value?

I've the following TabControl:

<TabControl  ItemsSource="{Binding Days}" Grid.Row="1" Margin="6" SelectedIndex="0" Loaded="OnTabLoaded">
    <TabControl.ItemContainerStyle>
        <Style TargetType="{x:Type TabItem}">
            <Setter Property="Header"  >
                <Setter.Value>
                    <Binding Path="Key" ConverterParameter="{}{0:ddd dd.MM}">
                        <Binding.Converter>
                            <converters:ToStringConverter></converters:ToStringConverter>
                        </Binding.Converter>

                    </Binding>
                </Setter.Value>
            </Setter>
            <Setter Property="Background" Value="IndianRed"></Setter>
            <Style.Triggers>
                <DataTrigger Binding="{Binding Value.HasError}" Value="False">
                    <Setter Property="Background" Value="LightGreen"></Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TabControl.ItemContainerStyle>
    
    <!-- Content -->
    
</TabControl>

Which basically set my tab header in specific color depending of the status of its content. But when I select a tab, the header is grey again.

How can I either keep the originally set color, either change the color of the tab based (again) on the value?

Share Improve this question asked Mar 13 at 7:12 J4NJ4N 20.8k42 gold badges222 silver badges384 bronze badges 1
  • Similar posts: 1, 2, 3. You could also try to only override TabItem.HeaderTemplate. – Sinatr Commented Mar 19 at 10:28
Add a comment  | 

1 Answer 1

Reset to default 0

The background color of the selected element (not only TabItem) starting with Win 8 is set in the element templates by a constant. Therefore, it can be changed either by changing the Element Template, or by finding the desired element in the visual tree at runtime.

Here is an example of a runtime solution using Attached Property.

The example assumes that the TabItem Template contains a Border element named innerBorder.

Unfortunately, there is no mandatory guarantee that such a template will always exist. WPF templates can be specified by the Windows theme, explicitly in the App resources, and in other ways.

Therefore, such a solution requires adjustment to the actual conditions.

    public static class TabItemHelper
    {
 
 
        public static Brush GetSelectedBackground(TabItem tabItem)
        {
            return (Brush)tabItem.GetValue(SelectedBackgroundProperty);
        }
 
        public static void SetSelectedBackground(TabItem tabItem, Brush brush)
        {
            tabItem.SetValue(SelectedBackgroundProperty, brush);
        }
 
        // Using a DependencyProperty as the backing store for SelectedBackground.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SelectedBackgroundProperty =
            DependencyProperty.RegisterAttached(nameof(SelectedBackgroundProperty)[0..^8],
                                                typeof(Brush),
                                                typeof(TabItemHelper),
                                                new PropertyMetadata(null)
                                                {
                                                    PropertyChangedCallback = OnSelectedBackgroundChanged
                                                });
 
        private static void OnSelectedBackgroundChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TabItem tabItem = (TabItem)d;
            if (e.NewValue is Brush brush)
            {
                tabItem.Loaded += OnTabItemLoaded;
                OnTabItemLoaded(tabItem, EventArgs.Empty);
            }
            else
            {
                tabItem.Loaded -= OnTabItemLoaded;
            }
        }
 
        private static void OnTabItemLoaded(object sender, EventArgs _)
        {
            TabItem tabItem = (TabItem)sender;
            if (tabItem.Template?.FindName("innerBorder", tabItem) is Border border)
            {
                border.Background = GetSelectedBackground(tabItem);
            }
        }
    }
        <TabControl Background="#f0f0f0">
            <TabControl.ItemContainerStyle>
                <Style TargetType="TabItem">
                    <Setter Property="local:TabItemHelper.SelectedBackground" Value="Green"/>
                </Style>
            </TabControl.ItemContainerStyle>
            <TabItem Header="Файл"
                     local:TabItemHelper.SelectedBackground="Aqua"></TabItem>
            <TabItem Header="Правка"></TabItem>
            <TabItem Header="Справка">
                <Border Background="Yellow"/>
            </TabItem>
        </TabControl>  

本文标签: cHow to keep the set background color of a TabControl39s headerStack Overflow