【问题标题】:Change WPF DataTemplate for ListBox item if selected如果选中,则更改列表框项的 WPF DataTemplate
【发布时间】:2008-09-28 17:10:39
【问题描述】:

我需要根据是否选择项目来更改 ListBox 中项目的 DataTemplate(选择时显示不同/更多信息)。

单击有问题的 ListBox 项目(仅通过选项卡)时,我没有在 DataTemplate(StackPanel)的最顶部元素上收到 GotFocus/LostFocus 事件,而且我没有想法。

【问题讨论】:

    标签: .net wpf


    【解决方案1】:

    最简单的方法是为“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}" />
    

    【讨论】:

    • 谢谢,请在您的帖子中包含 ,这样人们就不必在您的博客中搜索了。
    • 我在设置 ListBox 的 ContainerStyle 时遇到的一个问题是它会导致与主题不兼容。我使用了您的方法,但是当我从 WPF Futures 集中应用主题时,ListBoxItems 具有默认样式而不是主题样式。就我而言,黑色背景上的黑色文字和一般的丑陋。我仍在寻找另一种方法,可能使用 DataTemplate 触发器。
    • 另外,如果您希望新的 ItemContainerStyle 与主题兼容,则必须将其基于主题中的样式。为此,请将BasedOn="{StaticResource {x:Type ListBoxItem}}" 与 ListBox 一起使用。这也适用于 TreeView 等其他控件。
    • 在使用它时,我发现我必须在资源部分的样式上方声明 DataTemplates,以免出现神秘的 XAML 错误。只是一个提示。
    【解决方案2】:

    要在选择或不选择项目时设置样式,您只需在&lt;DataTemplate&gt; 中检索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>
    

    【讨论】:

    • 正如我在问题中所写,如果选择,我实际上会显示更多信息(“选择时显示不同/更多信息”)。尽管如此,如果这可以与切换某些元素的可见性(包括它们是否占用大小)一起工作,这将是一个可行的解决方案。虽然有一段时间没有使用 WPF。
    【解决方案3】:

    还应注意,堆栈面板不可聚焦,因此它永远不会获得焦点(如果您/真​​的/希望它获得焦点,请设置 Focusable=True)。但是,在这种情况下要记住的关键是 Stackpanel 是 TreeViewItem 的 child,在这种情况下是 ItemContainer。正如 Micah 所建议的,调整 itemcontainerstyle 是一个好方法。

    您可能可以使用 DataTemplates 以及诸如使用 RelativeSouce 标记扩展来查找 listviewitem 的数据触发器之类的东西来做到这一点

    【讨论】:

      猜你喜欢
      • 2017-02-27
      • 1970-01-01
      • 2016-03-03
      • 1970-01-01
      • 2010-09-19
      • 1970-01-01
      • 1970-01-01
      • 2010-12-29
      • 1970-01-01
      相关资源
      最近更新 更多