2011-11-05 30 views
1

我得到了一个ListBoxItem的一个DataTemplate,我想创建一个TRIGER,所以当用户点击一个项目的背景将改变,并在标签列表框,DataTemplate中和触发器

我的代码:

<Window.Resources> 
    <Style x:Key="RoundedItem" TargetType="ListBoxItem"> 
     <EventSetter Event="MouseDoubleClick" Handler="listViewItem_MouseDoubleClick" /> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="ListBoxItem"> 
        <Border Name="ItemBorder" CornerRadius="10" BorderBrush="Black" BorderThickness="1" Margin="1" Background="Transparent"> 
         <Label Name="ItemLabel" Foreground="Red" > 
          <ContentPresenter /> 
         </Label> 
        </Border> 

         <ControlTemplate.Triggers> 
         <Trigger Property="IsSelected" Value="True"> 
          <Setter TargetName="ItemBorder" Property="Background" Value="DeepSkyBlue" /> 
          <Setter TargetName="ItemLabel" Property="Foreground" Value="Orange" /> 
         </Trigger> 

        </ControlTemplate.Triggers> 
       </ControlTemplate> 

      </Setter.Value> 
     </Setter> 
    </Style> 

    <DataTemplate x:Key="TitleTemplate" DataType="models:Title" > 
     <StackPanel> 
       <Image Source="{Binding ThumbFilePath}" Width="50" HorizontalAlignment="Center"/> 
      <Label Content="{Binding Name}" HorizontalAlignment="Center" /> 
      <TextBlock Text="{Binding Description}" HorizontalAlignment="Center" TextWrapping="Wrap" Padding="5,5,5,5"/> 
     </StackPanel> 
    </DataTemplate> 

</Window.Resources> 

发生了什么是TextBlock的改变他的颜色和n ot标签..

有人知道为什么吗? 谢谢。

回答

4

TextBlock从其父项在视觉树中继承前景定义。另一方面,Label以其默认样式定义前景。

您的方法是“非WPF类型” - 您不应将ContentPresenter包装在Label控件中。

正确的做法取决于您是否想所有项目中的文本改变其前景,或只是标签?

[在这两种情况下,没有明显的好处在数据模板使用Label - 所以我会假设标签更改为TextBlock]

如果回答上述问题是所有的文字应改为:在ListBoxItemControlTemplate,在触发IsSelected,从seccond二传手删除TargetName="ItemLabel"所以最终制定者是:

<Setter Property="Foreground" Value="Orange" /> 

这将改变的前景该项目将影响数据模板中TextBlock的前景。

如果你想只影响的TextBlocks之一:

1. remove the setter for the foreground from the control template 
2. add a trigger to your data template: 

<DataTemplate> 
    <StackPanel> 
     <Image .../> 
     <TextBlock x:Name="Text01" ..../> 
     <TextBlock x:Name="Text02" ..../> 
    </StackPanel> 
    <DataTemplate.Triggers> 
     <DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}" Value="True"> 
      <Setter TargetName="Text01" Property="Foreground" Value="Orange"/> 
     </DataTrigger> 
    </DataTemplate.Triggers> 
</DataTemplate> 

附注:如果您在数据模板中使用Label控制,约束其前景属性列表框的前景项,像这样:

<Label Foreground="{Binding Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}"....../> 

如果这没有帮助,就意味着你的列表框项目继承其前景,所以使用:

<Label Foreground="{Binding TextElement.Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}"....../> 
+0

谢谢,很好的答案! – ibm123

1

我想解决这个问题,我遇到了类似的问题,我在ListBox中添加了一个ListBox.ItemTemplate,然后样式不再适用于文本。

我在做的是试图显示一个语言列表(CultureInfo)供用户选择,但我希望显示本机名称,而不是英文名称。由于某些原因,并非所有的语言都有在CultureInfo中大写的本地名,并且NativeName是它们名称的唯一实例,所以我需要将一个函数应用于CultureInfo。NativeName将我自己的名字大写。为了做到这一点,我添加了一个DataTemplate,里面有一个Data Template,我在其上应用了一个转换器。

<ListBox IsSynchronizedWithCurrentItem="True" VerticalAlignment="Center" MinHeight="200" x:Name="cbLanguages" 
    ItemsSource="{Binding Path=SupportedCultures, Mode=OneWay, Source={StaticResource CultureResourcesDS}}" 
    FontSize="24" HorizontalAlignment="Stretch" Width="300" Margin="10" 
    Style="{DynamicResource ListBoxTemplate}" ItemContainerStyle="{DynamicResource ListBoxItemStyle}"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <Label Content="{Binding Converter={StaticResource NativeNameConverter}}"/> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

一阵搜索后,我碰到XAMeLi的答案在这里,和改变了标签我放在DataTemplate中到一个文本框,我会创造了ListBoxItemStyle再次合作。

基本上,标签和文本框有不同的特点,可以被利用,或可能会导致在这种情况下恼人的问题。这里有一个很好的解释与差异的一些例子:http://joshsmithonwpf.wordpress.com/2007/07/04/differences-between-label-and-textblock/

相关问题