【发布时间】:2016-03-23 21:35:26
【问题描述】:
我有一个带有 ItemTemplateSelector 的 ListBox。模板选择器返回的所有数据模板都有一个边框。当鼠标悬停在边框上时,我想更改边框的背景颜色。为此,我在列表框中添加了一个带有 IsMouseOver 触发器的 ListBoxItem 控件模板,但我不知道如何从触发器的设置器中引用数据模板的边框。我最好的选择是以下二传手,但没有效果:
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Border.Background" Value="Yellow" />
</Trigger>
有没有办法在 XAML 中执行此操作,或者可能在代码中向下钻取可视化树以以某种方式找到边框?
我还想在列表框中选择项目时更改边框的背景颜色。我知道我可以将Foreground 更改为ListBoxItem 样式,如下所示:
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
但与Foreground不同,Background不被继承,所以DataTemplate中的Border不会收到触发器的刷子。
【问题讨论】:
-
项目模板应该触发外部发生的事情,而不是相反,因为没有办法知道里面发生了什么。另外,不要乱用视觉树,这不会有什么好处。
-
@H.B.没错,我可以将 IsMouseOver 触发器放在数据模板中,这样就解决了。但是数据模板永远不会知道它驻留在 ListBoxItem 中并且它已成为选定项,因此它应该改变颜色。还是会?只有 ListBox 知道,这就是我使用 ListBoxItem 控件模板的原因。
-
好吧,如果选择独立于
DataTemplate,问题是它是否应该首先影响模板中的任何内容。这不是一个人通常会做的事情。如果DataTemplate应该响应选择,那么首先将该逻辑放在DataTemplate中可能是有意义的。 -
@H.B.我想通过更改所选项目的
Border(由DataTemplate返回)的背景而不是ListBoxItem绘制的默认背景颜色更改来指示选择了哪个项目。我意识到控制模板无法访问Content的可视化树。相反,如果Background属性被继承,我可以使用样式(请参阅更新的帖子)。由于没有继承,所以我还没有找到解决办法。