【发布时间】:2008-09-28 17:10:39
【问题描述】:
我需要根据是否选择项目来更改 ListBox 中项目的 DataTemplate(选择时显示不同/更多信息)。
单击有问题的 ListBox 项目(仅通过选项卡)时,我没有在 DataTemplate(StackPanel)的最顶部元素上收到 GotFocus/LostFocus 事件,而且我没有想法。
【问题讨论】:
我需要根据是否选择项目来更改 ListBox 中项目的 DataTemplate(选择时显示不同/更多信息)。
单击有问题的 ListBox 项目(仅通过选项卡)时,我没有在 DataTemplate(StackPanel)的最顶部元素上收到 GotFocus/LostFocus 事件,而且我没有想法。
【问题讨论】:
最简单的方法是为“ItemContainerStyle”而不是“ItemTemplate”属性提供模板。在下面的代码中,我创建了 2 个数据模板:一个用于“未选中”,一个用于“选中”状态。然后,我为“ItemContainerStyle”创建一个模板,该模板是包含该项目的实际“ListBoxItem”。我将默认的“ContentTemplate”设置为“未选择”状态,然后提供一个触发器,当“IsSelected”属性为真时交换模板。 (注意:为简单起见,我将后面代码中的“ItemsSource”属性设置为字符串列表)
<Window.Resources>
<DataTemplate x:Key="ItemTemplate">
<TextBlock Text="{Binding}" Foreground="Red" />
</DataTemplate>
<DataTemplate x:Key="SelectedTemplate">
<TextBlock Text="{Binding}" Foreground="White" />
</DataTemplate>
<Style TargetType="{x:Type ListBoxItem}" x:Key="ContainerStyle">
<Setter Property="ContentTemplate" Value="{StaticResource ItemTemplate}" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="ContentTemplate" Value="{StaticResource SelectedTemplate}" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<ListBox x:Name="lstItems" ItemContainerStyle="{StaticResource ContainerStyle}" />
【讨论】:
BasedOn="{StaticResource {x:Type ListBoxItem}}" 与 ListBox 一起使用。这也适用于 TreeView 等其他控件。
要在选择或不选择项目时设置样式,您只需在<DataTemplate> 中检索ListBoxItem 父级并在其IsSelected 更改时触发样式更改。例如,下面的代码将创建一个TextBlock,默认为Foreground 颜色green。现在,如果项目被选中,字体将变为 red,当鼠标悬停在项目上时,该项目将变为 yellow。这样,您就无需按照其他答案中的建议为您希望稍微更改的每个状态指定单独的数据模板。
<DataTemplate x:Key="SimpleDataTemplate">
<TextBlock Text="{Binding}">
<TextBlock.Style>
<Style>
<Setter Property="TextBlock.Foreground" Value="Green"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsSelected, RelativeSource={
RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem }}}"
Value="True">
<Setter Property="TextBlock.Foreground" Value="Red"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=IsMouseOver, RelativeSource={
RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem }}}"
Value="True">
<Setter Property="TextBlock.Foreground" Value="Yellow"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
【讨论】:
还应注意,堆栈面板不可聚焦,因此它永远不会获得焦点(如果您/真的/希望它获得焦点,请设置 Focusable=True)。但是,在这种情况下要记住的关键是 Stackpanel 是 TreeViewItem 的 child,在这种情况下是 ItemContainer。正如 Micah 所建议的,调整 itemcontainerstyle 是一个好方法。
您可能可以使用 DataTemplates 以及诸如使用 RelativeSouce 标记扩展来查找 listviewitem 的数据触发器之类的东西来做到这一点
【讨论】: