Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
196 views
in Technique[技术] by (71.8m points)

c# - Change the Selected Color Listbox

I want to change the Selected Background and have it display a gradient with round corners. I've searched Google and found that some people do change the selected color by overriding the default color. Is there any way I can do this? I was thinking is there any way to display a round cornered border as the background when an item is selected?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here is the default style for a ListBoxItem (which is what we want to change). This style can be "retrieved" if you are using Expression Blend 4 by right clicking on a listboxitem in the Objects and Timelines control.

<Style x:Key="ListBoxItemStyle1" TargetType="{x:Type ListBoxItem}">
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
    <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
    <Setter Property="Padding" Value="2,0,0,0"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListBoxItem}">
                <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" 
                BorderThickness="{TemplateBinding BorderThickness}" 
                Background="{TemplateBinding Background}" 
                Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true"
                >
                    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsSelected" Value="true">
                        <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
                    </Trigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsSelected" Value="true"/>
                            <Condition Property="Selector.IsSelectionActive" Value="false"/>
                        </MultiTrigger.Conditions>
                        <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
                    </MultiTrigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Let's pull out some important parts so that you learn to do this yourself.

<Style x:Key="ListBoxItemStyle1" TargetType="{x:Type ListBoxItem}">

This is the start of the Style declaration. We've given it a x:Key so it can be retrieved from a resource dictionary, and we've set the TargetType for ListBoxItem.

Now, we want to look for the portion of the style that we want to change. In this case, we're going to go down and look for a section of the style that is a MultiTrigger on the new ControlTemplate.

<MultiTrigger>
<MultiTrigger.Conditions>
        <Condition Property="IsSelected" Value="true"/>
        <Condition Property="Selector.IsSelectionActive" Value="false"/>
    </MultiTrigger.Conditions>
    <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
</MultiTrigger>

This MultiTrigger needs 2 properties to match the values in order to be activated. This trigger, when activated, will change the background color to Value="..." and the foreground color to Value="...". In order to get a gradient background, we need to change the value in the Background Value="..." to a different brush. Let's create a quick little gradient brush (very colorful one too!)

<LinearGradientBrush x:Key="GradientBrush" StartPoint="0,0" EndPoint="1,1">
      <GradientStop Color="Yellow" Offset="0.0" />
      <GradientStop Color="Red" Offset="0.25" />
      <GradientStop Color="Blue" Offset="0.75" />
      <GradientStop Color="LimeGreen" Offset="1.0" />
</LinearGradientBrush>

So now let's apply this to the Background of this trigger.

<Setter Property="Background" TargetName="Bd" Value="{StaticResource GradientBrush}"/>

Now, when this style is applied to the ListBoxItem, and the ListBoxItem IsSelected = True (and Selector.IsSelectionActive = false) you'll see a gradient background on the listboxitem.

Now, you also wanted rounded corners. If we go way up to the top of the ControlTemplate, we'll see a border declaration.

<Border x:Name="Bd"

In that declaration, we want to add a CornerRadius attribute to get the corners rounded on the ListBoxItem.

CornerRadius="5"

And now, you should be able to create a corner radius, linear gradient background listboxitem. I hope that you'll be able to carry on from here on your own.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...