我有一个ListBox,其中每个项目都是StackPanel。 StackPanel由一个Image和一个TextBlock组成:
info
看起来像这样:
当用户选择一个项目时,我得到StackPanel周围的默认蓝色矩形:
现在,我想为所选项目制作不同的边框,但我希望 仅围绕图像 。
我知道如何创建一个控件模板并在ContentPresenter周围放置一个自定义边框,但这当然会围绕整个StackPanel,而不仅仅是Image。
我不知道是否可以对ContentPresenter进行更改,如果这是一个好主意。如果还有其他方法可以实现我想要的外观,那么它也会很好。
答案 0 :(得分:1)
是的,ListBox自己的ContentPresenter对你正在做的事情没有帮助。你想a)消除ListBox自己的选择视觉效果,b)用更适合你的项目的DataTemplate替换它们。
默认选择视觉效果由ListBoxItem
的默认模板应用。所以替换那个模板。在ListBox
的资源中使用样式,将您自己的控件模板应用于ListBoxItem
。不多,只提出内容,不提供选择背景。然后,您可以使用数据模板中的触发器处理选择视觉效果,其中您的图像和标签已定义,您可以将更改应用于一个而不是另一个。以下示例适用于我。
请注意,有一些摆弄Border元素上的HorizontalAlignment,使其依赖于其中的Image元素。另外,我编写了一个quickie测试视图模型,其Items属性称为Items
;我假设这不是您用来填充自己的ListBox的集合成员的名称。
<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>