WPF 样式 TabControl TabItems 自定义 Foreground/Background 颜色

WPF styling TabControl TabItems custom Foreground/Background colors

我是 WPF 的新手 -- 被各种可能性所吸引,但感到沮丧....我正在努力使 TabControl 上的不同选项卡根据时间具有不同的 foregound/background 颜色他们被选中了。我做的第一件事是创建名为 PlayerTabItem 的新 TabItem class 并给它一个 Brush SelectedBackground 属性。这是一个音乐播放器应用程序,因此 "player" 在此上下文中指的是它在此应用程序中的使用。 (我首先将 SelectedBackground 创建为一个简单的 属性,然后作为依赖项 属性,但这似乎没有改变任何东西,所以我省略了那个实现。)

class PlayerTabItem : TabItem
{
    public Brush SelectedBackground { get; set; }
}

然后我在我的XAML中使用了这个,编译成功了(只要我把"local:"放在标签名前面),并识别出新的属性我创建。当然,属性 什么也没做。这就是我卡住的地方。

<local:PlayerTabItem Header="Now Playing" SelectedBackground="Blue"/>
<local:PlayerTabItem Header="Collection" SelectedBackground="Purple"/>
<local:PlayerTabItem Header="Search" SelectedBackground="Green"/>

我尝试处理 PlayerTabItem class 中的选择事件以应用背景颜色,但这是一个死胡同。 (覆盖 PlayerTabItem.OnSelected 并设置颜色没有效果 - 运行 没有错误但什么也没做。)然后我尝试添加一个带有新 ControlTemplate 的样式和一个 IsSelected = true 的触发器,然后我开始得到更近......如果我只是在 Trigger.Setter:

中硬编码一种颜色,它就会起作用
<Trigger Property="IsSelected" Value="True">
   <Setter TargetName="Panel" Property="Background" Value="Purple" />
</Trigger>

但我真正想要的是绑定到 PlayerTabItem 的 SelectedBackground 颜色。我试过这个:

<Setter TargetName="Panel" Property="Background" Value="{Binding SelectedBackground}" />

但是没有效果。我怀疑我需要某种关于绑定的 Path 参数,但我不知道是什么。我尝试使用 XAMLSpy 来帮助我了解正在发生的事情(就元素的层次结构和可能的绑定路径而言),但我并没有走得太远——除了当我试图设置SelectedBackground 属性 通过 XAMLSpy,它报告找不到 属性 SelectedBackground。怎么可能呢? ....因为我已经编译并且运行程序没有错误。

我希望我正在尝试做的事情有意义 -- 我只想在选项卡控件上更改选定选项卡的背景颜色。

  1. 要更改选项卡颜色,请编辑模板控件并删除触发器:
    在大纲中 window 右键单击​​ PlayerTabItem:编辑 Template/Edit 一个副本。
    您还可以修改触发器以根据焦点、悬停、...

  2. 应用某些样式
  3. 首先在PlayerTabItem中创建两个依赖属性(snippet propdp + tabulation twice),监听IsSelected的变化属性:

    class PlayerTabItem : TabItem
    {
        public PlayerTabItem()
        {
            Loaded += (sender, e) => { Background = IsSelected ? SelectedBackground : UnSelectedBackground; };
            DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty(TabItem.IsSelectedProperty, typeof(TabItem));
            dpd.AddValueChanged(this, (sender, args) =>
            {
                Background = IsSelected ? SelectedBackground : UnSelectedBackground;
                System.Diagnostics.Debug.WriteLine("Changing background of {0} to {1}", this.Header, this.Background);
            });
        }
        public Brush SelectedBackground
        {
            get { return (Brush)GetValue(SelectedBackgroundProperty); }
            set { SetValue(SelectedBackgroundProperty, value); }
        }
        public static readonly DependencyProperty SelectedBackgroundProperty =
            DependencyProperty.Register("SelectedBackground", typeof(Brush), typeof(PlayerTabItem), new PropertyMetadata(null));
        public Brush UnSelectedBackground
        {
            get { return (Brush)GetValue(UnSelectedBackgroundProperty); }
            set { SetValue(UnSelectedBackgroundProperty, value); }
        }
        public static readonly DependencyProperty UnSelectedBackgroundProperty =
            DependencyProperty.Register("UnSelectedBackground", typeof(Brush), typeof(PlayerTabItem), new PropertyMetadata(null));
    }
    
  4. 因此可以使用依赖属性声明控件,并在进行选择时查看颜色变化

    <TabControl >
        <local:PlayerTabItem SelectedBackground="Red" UnSelectedBackground="Pink"  Header="Tab1" Style="{DynamicResource PlayerTabItemStyle1}" />
        <local:PlayerTabItem SelectedBackground="Yellow" UnSelectedBackground="Pink" Header="Tab2" Style="{DynamicResource PlayerTabItemStyle1}"/>
        <local:PlayerTabItem SelectedBackground="Green" UnSelectedBackground="Pink" Header="Tab3" Style="{DynamicResource PlayerTabItemStyle1}"/>
    </TabControl>
    

我承认肯定有更好的办法不用监听事件,只用触发器。但我无法让它工作。

请注意,在我的示例中,颜色很简单(红色...),但您可以使用任何画笔作为颜色

link 这里有一个完整的工作演示:http://1drv.ms/1NfCl9z

最佳编码