WPF 样式 TabControl TabItems 自定义前景色/背景色

Posted

技术标签:

【中文标题】WPF 样式 TabControl TabItems 自定义前景色/背景色【英文标题】:WPF styling TabControl TabItems custom Foreground/Background colors 【发布时间】:2016-01-01 10:46:08 【问题描述】:

我对 WPF 很陌生——被各种可能性所吸引,但感到沮丧.... .我做的第一件事是创建一个名为 PlayerTabItem 的新 TabItem 类,并给它一个 Brush SelectedBackground 属性。这是一个音乐播放器应用程序,因此本文中的“播放器”指的是它在此应用程序中的使用。 (我首先将 SelectedBackground 创建为一个简单的属性,然后将其创建为一个依赖属性,但这似乎并没有改变任何东西,所以我省略了该实现。)

class PlayerTabItem : TabItem

    public Brush SelectedBackground  get; set; 

然后我在我的 XAML 中使用了 this,它编译好(只要我在标签名称前加上“local:”),并识别出我创建的新属性。当然,该物业没有做任何事情。这就是我卡住的地方。

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

我尝试在 PlayerTabItem 类中处理选择事件以应用背景颜色,但这是一条死胡同。 (覆盖 PlayerTabItem.OnSelected 并设置颜色没有任何效果 - 运行没有错误但什么也没做。)然后我尝试添加一个带有新 ControlTemplate 的 Style 和一个 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 来帮助我了解正在发生的事情(就元素的层次结构和可能的绑定路径而言),但我并没有走得太远——除了当我尝试通过 XAMLSpy 设置 SelectedBackground 属性时,它报告未找到属性 SelectedBackground。怎么可能? ....因为我已经编译并运行程序没有错误。

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

【问题讨论】:

1) 如果你想绑定你自己的属性,你是对的:你需要声明一个依赖属性。因此,将它放在控件中会更好,也更合乎逻辑。 2)您希望 TabItem 的背景颜色在选择时有所不同,对吧? 是的,我想要实现的目标是正确的 【参考方案1】:

    为了改变标签颜色,编辑模板控件,并移除触发器: 在大纲窗口中右键单击 PlayerTabItem:编辑模板/编辑副本。 您还可以根据焦点、悬停等修改触发器以应用某种样式...

    首先在PlayerTabItem中创建两个依赖属性(sn -p propdp + tabulation两次),监听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));
    
    

    因此可以使用依赖属性声明控件并在选择时查看颜色变化

    <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>
    

我承认,在不监听事件的情况下,只使用触发器必须有更好的方法。但我无法让它工作。

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

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

最佳编码

【讨论】:

感谢您的详细回复——我会尽快看看! @Adam:你看过回复了吗?我想我回答了你的问题 抱歉,这周很忙——本周末再看——再次感谢您抽出宝贵时间

以上是关于WPF 样式 TabControl TabItems 自定义前景色/背景色的主要内容,如果未能解决你的问题,请参考以下文章

WPF 样式 TabControl TabItems 自定义前景色/背景色

WPF TabControl 覆盖 TabItem 背景?

WPF Adorner 在TabControl切换TabItem时消失

如何将自定义控件派生的 TabItem 添加到 WPF 中的 TabControl?

WPF中tabControl如何切换TabItem

WPF TabControl only load the selected TabItem