Wpf ListBox–更改ContentPresenter中默认的选定项样式*

Wpf ListBox–更改ContentPresenter中默认的选定项样式*,wpf,listbox,custom-controls,controltemplate,Wpf,Listbox,Custom Controls,Controltemplate,我有一个列表框,其中每个项目都是一个StackPanel。StackPanel由图像和其下方的文本块组成: <ListBox.ItemTemplate> <DataTemplate> <StackPanel Margin="10"> <Image> <Image.Source> <BitmapImage U

我有一个列表框,其中每个项目都是一个StackPanel。StackPanel由图像和其下方的文本块组成:

<ListBox.ItemTemplate>

    <DataTemplate>

        <StackPanel Margin="10">

            <Image>
                <Image.Source>
                    <BitmapImage UriSource="{Binding Path=ImageFilePath}"/>
                </Image.Source>
            </Image>

            <TextBlock Text="Title" TextAlignment="Center"/>

        </StackPanel>

   </DataTemplate>

</ListBox.ItemTemplate>
看起来是这样的:

当用户选择一个项目时,我会得到环绕StackPanel的默认蓝色矩形:

现在,我想为所选项目创建一个不同的边框,但我希望它仅围绕图像

我知道如何制作控件模板,并在ContentPresenter周围放置自定义边框,但这当然会围绕整个StackPanel,而不仅仅是图像


我不知道是否可以对ContentPresenter进行更改,也不知道这是否是一个好主意。如果有其他方法实现我想要的外观,也可以。

对,ListBox自己的ContentPresenter对您的操作没有帮助。您希望a消除列表框自己的选择视觉效果,b用数据模板中更适合您的项目的内容替换它们

默认的视觉选择由ListBoxItem的默认模板应用。因此,请替换该模板。使用ListBox参考资料中的样式,将自己的控件模板应用于ListBoxItem。没什么大不了的,只是呈现内容,不提供选择背景。然后使用数据模板中的触发器处理选择视觉效果,其中定义了图像和标签,可以对其中一个应用更改,而不能对另一个应用更改。下面的例子对我很有用

请注意,边界元素上的水平对齐有一些改动,使其与其中的图像元素保持一致。此外,我还编写了一个快速测试viewmodel,其Items属性称为Items;我假设这不是用于填充自己的列表框的集合成员的名称

<ListBox
    Margin="8"
    ItemsSource="{Binding Items}"
    >
    <ListBox.Resources>
        <Style TargetType="{x:Type ListBoxItem}">
            <Setter Property="HorizontalContentAlignment" Value="Stretch" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBoxItem}">
                        <Grid>
                            <ContentPresenter />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.Resources>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Border
                    x:Name="HighlightBorder"
                    BorderThickness="4"
                    HorizontalAlignment="Left"
                    VerticalAlignment="Top"
                    Margin="10"
                    >
                    <Border.Style>
                        <Style TargetType="Border">
                            <!-- MUST set default BorderBrush via a style, if you set it at all. 
                            As an attribute on the Border tag, it would override the effects of 
                            the trigger below. 
                            -->
                            <Setter Property="BorderBrush" Value="Transparent" />
                        </Style>
                    </Border.Style>
                    <Image Source="{Binding ImageFilePath}" />
                </Border>
            </Grid>
            <DataTemplate.Triggers>
                <DataTrigger 
                    Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=ListBoxItem}}" 
                    Value="True">
                    <Setter TargetName="HighlightBorder" Property="BorderBrush" Value="Orange" />
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

工作起来很有魅力。我也没有任何问题设置作为属性的边界笔刷。非常感谢。@Boohoo这很有趣;在WPF中,如果在边框上放置BorderBrush=蓝色,则选定项上的边框笔刷将保持蓝色。这是我在WPF的一贯经验;它不时地咬我。不管怎样,很高兴它对你有用。干杯