2008-09-28 101 views
83

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

当单击有问题的列表框项目(仅通过Tab键)时,DataTemplate(StackPanel)中的顶部元素无法获得GotFocus/LostFocus事件,并且我不知道该如何处理。

回答

167

最简单的方法是为“ItemContainerStyle”提供模板,而不是“ItemTemplate”属性。在下面的代码中,我创建了两个数据模板:一个用于“未选中”和一个用于“已选”状态。然后,我为“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}" /> 
+0

谢谢,请包括<列表框ItemContainerStyle =” {StaticResource的ContainerStyle}”的ItemsSource =” {结合迈德特}” />在您的文章,所以人们不必在您的博客搜索。 – Shimmy 2009-09-09 02:48:39

+1

设置ListBox的ContainerStyle时遇到的一个问题是它导致与主题不兼容。我使用了你的方法,但是当我使用WPF Futures集合中的主题时,ListBoxItems具有默认样式而不是主题样式。就我而言,黑色背景上的黑色文字和一般的丑陋。我仍在寻找另一种方法,可能使用DataTemplate触发器。 – 2010-02-01 03:13:14

6

还应当指出的是,StackPanel的不focuable,所以它永远不会得到焦点(设置Focusable = True,如果你/真的/想要它聚焦)。但是,在这种情况下要记住的关键是TreeViewItem的StackPanel是,在这种情况下它是ItemContainer。正如Micah所建议的,调整itemcontainerstyle是一个好方法。

你也许可以做到这一点使用的DataTemplates,事情如当项目被选中或不是所有你需要做的是将使用RelativeSouce标记扩展来寻找一个ListViewItem

6

要设置的样式datatriggers在<DataTemplate>中检索ListBoxItem父级,并在其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>