wpf修改控件默认样式(以修改ListBox默认样式为例)
日常开发中,需要展示大量数据时,我们常常会用到ListBox、ListView等条目控件。下面以ListBox为例,来详细说明一下如何修改控件的默认样式。
众所周知,点击ListBox控件的其中一项时,会出现深蓝色选中背景,文字颜色变为白色,如图:
此时,若我们点击其它地方的按钮,这时,由于焦点丢失,选中项的背景色变成了灰色,文字颜色变为黑色,如图:
很容易想到,这些颜色既然不是我们设置的,必然就是系统早就定义好的了。那么,如果我们不想使用这些系统默认样式,想自己定义一个,如点击时会出现金色渐变背景,文字变为绿色,失去焦点时会出现亮绿色渐变背景,文字变为蓝色,该怎么办呢?
首先需要考虑的是,如果要达到我们的目标,需要改动的到底是哪个控件的样式:ListBox还是ListBoxItem。这个,很好理解,需要修改的是ListBoxItem的样式。当然,如果想不到这一点的话,也很容易定位到这里:(在此,先推荐一个小工具WPF Inspector)用Inspector查看,定位到ListBox的选中项,截图如下:
于是,很容易的,我们就明白了,想要达到我们的目的,我们需要修改的是ListBoxItem的样式。
那么,ListBoxItem的默认样式是怎样的呢?在此,再推荐一个小工具XamlPadX,安装后,我们可以在安装目录下找到一个名为ControlStyle.exe的文件,点击直接运行,在下拉框中选择ListBoxItem,于是ListBoxItem的默认样式就出现在我们面前了:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<Style TargetType="ListBoxItem" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Style.Resources> <ResourceDictionary /> </Style.Resources> <Setter Property="Panel.Background"> <Setter.Value> <SolidColorBrush>#00FFFFFF</SolidColorBrush> </Setter.Value> </Setter> <Setter Property="Control.HorizontalContentAlignment"> <Setter.Value> <Binding Path="HorizontalContentAlignment" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ItemsControl, AncestorLevel=1}" /> </Setter.Value> </Setter> <Setter Property="Control.VerticalContentAlignment"> <Setter.Value> <Binding Path="VerticalContentAlignment" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ItemsControl, AncestorLevel=1}" /> </Setter.Value> </Setter> <Setter Property="Control.Padding"> <Setter.Value> <Thickness>2,0,0,0</Thickness> </Setter.Value> </Setter> <Setter Property="Control.Template"> <Setter.Value> <ControlTemplate TargetType="ListBoxItem"> <Border BorderThickness="{TemplateBinding Border.BorderThickness}" Padding="{TemplateBinding Control.Padding}" BorderBrush="{TemplateBinding Border.BorderBrush}" Background="{TemplateBinding Panel.Background}" Name="Bd" SnapsToDevicePixels="True"> <ContentPresenter Content="{TemplateBinding ContentControl.Content}" ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}" ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}" HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" /> </Border> <ControlTemplate.Triggers> <Trigger Property="Selector.IsSelected"> <Setter Property="Panel.Background" TargetName="Bd"> <Setter.Value> <DynamicResource ResourceKey="{x:Static SystemColors.HighlightBrushKey}" /> </Setter.Value> </Setter> <Setter Property="TextElement.Foreground"> <Setter.Value> <DynamicResource ResourceKey="{x:Static SystemColors.HighlightTextBrushKey}" /> </Setter.Value> </Setter> <Trigger.Value> <s:Boolean>True</s:Boolean> </Trigger.Value> </Trigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="Selector.IsSelected"> <Condition.Value> <s:Boolean>True</s:Boolean> </Condition.Value> </Condition> <Condition Property="Selector.IsSelectionActive"> <Condition.Value> <s:Boolean>False</s:Boolean> </Condition.Value> </Condition> </MultiTrigger.Conditions> <Setter Property="Panel.Background" TargetName="Bd"> <Setter.Value> <DynamicResource ResourceKey="{x:Static SystemColors.ControlBrushKey}" /> </Setter.Value> </Setter> <Setter Property="TextElement.Foreground"> <Setter.Value> <DynamicResource ResourceKey="{x:Static SystemColors.ControlTextBrushKey}" /> </Setter.Value> </Setter> </MultiTrigger> <Trigger Property="UIElement.IsEnabled"> <Setter Property="TextElement.Foreground"> <Setter.Value> <DynamicResource ResourceKey="{x:Static SystemColors.GrayTextBrushKey}" /> </Setter.Value> </Setter> <Trigger.Value> <s:Boolean>False</s:Boolean> </Trigger.Value> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
分析这个样式,不难发现,只要我们有办法将SystemColors.HighlightBrushKey、SystemColors.HighlightTextBrushKey、SystemColors.ControlBrushKey、SystemColors.ControlTextBrushKey这四个样式给替换了,那就一切OK。
这个问题可以通过这种方式实现:
首先定义ListBoxItem的样式,代码如下:
<Style x:Key="listBoxItemStyle" TargetType="ListBoxItem"> <Style.Resources> <!--高亮状态(选中且有焦点)--> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0" x:Key="{x:Static SystemColors.HighlightBrushKey}"> <GradientStop Color="White" Offset="0"/> <GradientStop Color="#FFFFE47A" Offset="1"/> </LinearGradientBrush> <SolidColorBrush Color="Green" x:Key="{x:Static SystemColors.HighlightTextBrushKey}"/> <!--选中状态(选中但失去焦点)--> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0" x:Key="{x:Static SystemColors.ControlBrushKey}"> <GradientStop Color="White" Offset="0"/> <GradientStop Color="#FF42F006" Offset="1"/> </LinearGradientBrush> <SolidColorBrush Color="Blue" x:Key="{x:Static SystemColors.ControlTextBrushKey}"/> </Style.Resources> </Style>
然后应用这个样式就行了:在ListBox中设置ItemContainerStyle="{StaticResource listBoxItemStyle}"
最后,运行一下,就可以看到我们想要的效果了。