wpf修改控件默认样式(以修改ListBox默认样式为例)

日常开发中,需要展示大量数据时,我们常常会用到ListBox、ListView等条目控件。下面以ListBox为例,来详细说明一下如何修改控件的默认样式。

众所周知,点击ListBox控件的其中一项时,会出现深蓝色选中背景,文字颜色变为白色,如图:

此时,若我们点击其它地方的按钮,这时,由于焦点丢失,选中项的背景色变成了灰色,文字颜色变为黑色,如图:

很容易想到,这些颜色既然不是我们设置的,必然就是系统早就定义好的了。那么,如果我们不想使用这些系统默认样式,想自己定义一个,如点击时会出现金色渐变背景,文字变为绿色,失去焦点时会出现亮绿色渐变背景,文字变为蓝色,该怎么办呢?

首先需要考虑的是,如果要达到我们的目标,需要改动的到底是哪个控件的样式:ListBox还是ListBoxItem。这个,很好理解,需要修改的是ListBoxItem的样式。当然,如果想不到这一点的话,也很容易定位到这里:(在此,先推荐一个小工具WPF Inspector)用Inspector查看,定位到ListBox的选中项,截图如下:

于是,很容易的,我们就明白了,想要达到我们的目的,我们需要修改的是ListBoxItem的样式。

那么,ListBoxItem的默认样式是怎样的呢?在此,再推荐一个小工具XamlPadX,安装后,我们可以在安装目录下找到一个名为ControlStyle.exe的文件,点击直接运行,在下拉框中选择ListBoxItem,于是ListBoxItem的默认样式就出现在我们面前了:

View Code
<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}"

最后,运行一下,就可以看到我们想要的效果了。

posted @ 2013-03-15 16:37  xuejiao  阅读(3657)  评论(0编辑  收藏  举报