选中时保持ListBoxItem的coustum样式

时间:2013-08-27 13:14:31

标签: c# wpf mvvm

我有一个ListBox,其中项目的背景颜色绑定到条目的某些属性:

<ListBox ItemsSource="{Binding ObservableCollectionOfFoos}" >
    <ListBox.ItemContainerStyle >
        <Style TargetType="ListBoxItem" >
            <Setter Property="Content" Value="{Binding SomePropertyOfFoo}"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding AnotherPropertyOfFoo}" Value="true">
                    <Setter Property="Background" Value="Green" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

这样可行,但是当我鼠标悬停或选择一个项目时,背景会改变(不出所料)或者是默认的鼠标悬停/选定颜色。

我是WPF的新手,我不确定我是否会正确地做这种事情,我想也许我需要使用ItemContainerStyleSelector,但我对如何使用它感到困惑,而且它为这件小事创建一个类似乎很愚蠢......

我还想到的是从布尔到颜色创建一个IValueConverter,然后通过它绑定而不必使用DataTrigger作为一种不同的方法,那会更优雅吗?那会有些帮我解决这个问题吗?

修改

如果我可以根据AnotherPropertyOfFoo将所选项目的背景颜色更改为不同的颜色,如果它不是太多要求

那也很好

编辑2(评论@Sheridan答案的扩展名):

这不起作用

    <ListBox>
        <ListBox.Items>
            <ListBoxItem>one</ListBoxItem>
            <ListBoxItem>two</ListBoxItem>
            <ListBoxItem>three</ListBoxItem>
            <ListBoxItem>four</ListBoxItem>
        </ListBox.Items>
        <ListBox.ItemContainerStyle>
            <Style TargetType="ListBoxItem">
                <Setter Property="Background" Value="Green" />
                <Style.Resources>
                    <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Red" />
                    <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Red" />
                    <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black" />
                    <SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="Black" />
                </Style.Resources>
            </Style>
        </ListBox.ItemContainerStyle>
    </ListBox>

2 个答案:

答案 0 :(得分:1)

您还可以覆盖ListBoxItem的模板,使用混合和覆盖提取默认值或使用此处已提到的some

修改

实际上覆盖模板:)并不是那么难,我想这是解决问题的最正确方法。试试这个ItemContainer风格。它取代了默认的ListBoxItem样式 - &gt;模板。要查看它是如何工作的 - 在触发器中,您可以更改列表框项的任何属性。

 <ListBox.ItemContainerStyle>
            <Style TargetType="{x:Type ListBoxItem}">
                <Setter Property="Background" Value="Transparent"/>
                <Setter Property="Padding" Value="2,0,0,0"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ListBoxItem">
                            <Border Name="Border" Padding="2" SnapsToDevicePixels="true">
                                <ContentPresenter />
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsMouseOver" Value="true">
                                    <Setter TargetName="Border" Property="Background" Value="LightBlue"/>
                                </Trigger>
                                <Trigger Property="IsSelected" Value="true">
                                    <Setter TargetName="Border" Property="Background" Value="Blue"/>
                                </Trigger>
                                <Trigger Property="IsEnabled" Value="false">
                                    <Setter Property="Foreground" Value="Gray"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ListBox.ItemContainerStyle>

ListBoxItem的默认样式,您可以找到here进行必要的修改。

答案 1 :(得分:0)

尝试使用:

<ListBox ItemsSource="{Binding ObservableCollectionOfFoos}" >
    <ListBox.ItemContainerStyle >
        <Style TargetType="ListBoxItem" >
            <Setter Property="Content" Value="{Binding SomePropertyOfFoo}"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding AnotherPropertyOfFoo}" Value="true">
                    <Setter Property="Background" Value="Green" />
                </DataTrigger>
            </Style.Triggers>
            <Style.Resources>
                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent" />
                <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent" />
                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black" />
                <SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="Black" />
            </Style.Resources>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

SystemColors.HighlightBrushKey表示集合控件中所选项目的默认背景颜色...此处设置为Transparent,但您可以将其设置为您喜欢的颜色。

更新&gt;&gt;&gt;

此代码工作正常......如果您将SolidColorBrush部分中的第一个Resources更改为Red,则所选项目背景颜色将为RedBinding AnotherPropertyOfFoo <ListBox ItemsSource="{Binding ObservableCollectionOfFoos}" > <ListBox.ItemContainerStyle > <Style TargetType="ListBoxItem" > <Setter Property="Content" Value="{Binding SomePropertyOfFoo}"/> <Style.Triggers> <Trigger Property="IsSelected" Value="True"> <Setter Property="Background" Value="{Binding AnotherPropertyOfFoo}" /> </DataTrigger> </Style.Triggers> <Style.Resources> <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent" /> <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent" /> <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black" /> <SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="Black" /> </Style.Resources> </Style> </ListBox.ItemContainerStyle> </ListBox> 不会影响所选项目,因为两者之间没有任何关系。为此,您可以尝试这样做:

AnotherPropertyOfFoo

现在,所选项目将从{{1}}属性中获取背景颜色。