如果选中,则更改ListBox项的WPF DataTemplate

时间:2008-09-28 17:10:39

标签: .net wpf

我需要更改ListBox中项目的DataTemplate,具体取决于项目是否被选中(选中时显示不同/更多信息)。

当单击有问题的ListBox项目时(仅通过Tab键),我没有在DataTemplate(StackPanel)的最顶层元素上获得GotFocus / LostFocus事件,而且我没有想法。

3 个答案:

答案 0 :(得分:173)

最简单的方法是为“ItemContainerStyle”而不是“ItemTemplate”属性提供模板。在下面的代码中,我创建了2个数据模板:一个用于“未选定”,另一个用于“选定”状态。然后我为“ItemContainerStyle”创建一个模板,它是包含该项的实际“ListBoxItem”。我将默认的“ContentTemplate”设置为“Unselected”状态,然后提供一个触发器,当“IsSelected”属性为true时,该触发器交换模板。 (注意:为了简单起见,我在后面的代码中将“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}" />

答案 1 :(得分:7)

要在选择项目时设置样式,您需要做的只是检索ListBoxItem中的<DataTemplate>父项,并在IsSelected更改时触发样式更改。例如,下面的代码将创建TextBlock,默认Foreground颜色绿色。现在,如果项目被选中,字体将变为红色,当鼠标结束时,项目将变为黄色。这样您就不需要像其他答案中所建议的那样为每个您想稍微改变的状态指定单独的数据模板。

<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>

答案 2 :(得分:6)

还应该注意,stackpanel是不可聚焦的,所以它永远不会得到焦点(如果你/真的/希望它聚焦,设置Focusable = True)。但是,在这样的场景中要记住的关键是StackPanel是TreeViewItem的 child ,在这种情况下是ItemContainer。正如Micah所说,调整itemcontainerstyle是一个很好的方法。

您可以使用DataTemplates,以及使用RelativeSouce标记扩展来查找listviewitem的数据触发器等内容