2010-09-01 83 views
11

我有一个WPF DataGrid有一个AlternatingRowBackground笔刷。它被配置为每隔一行着色。我想在鼠标悬停上做些事情,突出显示当前行。然而,风格触发器似乎失去了AlternatingRowBackground笔刷。我在鼠标上得到所需的行着色......但只在没有用AlternatingRowBackground笔刷绘制的行上。WPF风格触发DataGridRow背景颜色Trumped by AlternatingRowBackground笔刷

这里是Windows.Resources的风格:

<Window.Resources> 
     <ResourceDictionary> 
      <ResourceDictionary.MergedDictionaries> 
       <ResourceDictionary Source="/Skins/MainSkin.xaml" /> 
      </ResourceDictionary.MergedDictionaries> 
      <Style TargetType="{x:Type DataGridRow}"> 
       <Style.Triggers> 
        <Trigger Property="IsMouseOver" 
          Value="True"> 
         <Setter Property="Background" 
           Value="Red" /> 
         <Setter Property="FontWeight" 
           Value="ExtraBold" /> 
         <Setter Property="Height" 
           Value="20" /> 
        </Trigger> 
       </Style.Triggers> 
      </Style> 
     </ResourceDictionary> 
    </Window.Resources> 

这里是DataGrid中:

<DataGrid Margin="25,15,25,0" 
       VerticalAlignment="Top" 
       ItemsSource="{Binding DocumentTypeList}" 
       AutoGenerateColumns="False" 
       Height="500" 
       AlternationCount="2" 
       FrozenColumnCount="2" 
       AlternatingRowBackground="{DynamicResource AlternatingRow}"> 
     <DataGrid.Columns> 
      <DataGridTextColumn Binding="{Binding Abbreviation}" 
           Header="Abbreviation" /> 
      <DataGridTextColumn Binding="{Binding Title}" 
           Header="Title" /> 

      <DataGridTextColumn Binding="{Binding Fee}" 
           Header="Fee" /> 
      <DataGridTextColumn Binding="{Binding SpecialInstructions}" 
           Header="Special Instructions" /> 
     </DataGrid.Columns> 
    </DataGrid> 

是否有申报的绝对赢家的方法吗?这个问题是否是一个层次结构?在我看来,AlternatingRowBackground笔刷胜出,因为它直接与声明的最具体部分相关联。

更新:下面是正确的语法,基于@瓦尔的指导:

<Window.Resources> 
    <ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="/Skins/MainSkin.xaml" /> 
     </ResourceDictionary.MergedDictionaries> 
     <Style TargetType="{x:Type DataGridRow}"> 
      <Style.Triggers> 
       <Trigger Property="IsMouseOver" 
         Value="True"> 
        <Setter Property="Background" 
          Value="Red" /> 
        <Setter Property="FontWeight" 
          Value="ExtraBold" /> 
        <Setter Property="Height" 
          Value="20" /> 
       </Trigger> 
      </Style.Triggers> 
     </Style> 
     <Style TargetType="{x:Type DataGrid}"> 
      <Setter Property="AlternatingRowBackground" Value="{DynamicResource AlternatingRow}"/> 
     </Style> 
    </ResourceDictionary> 
</Window.Resources> 

而且在DataGrid(减去AlternatingRowBackground刷):

<DataGrid Margin="25,15,25,0" 
       VerticalAlignment="Top" 
       ItemsSource="{Binding DocumentTypeList}" 
       AutoGenerateColumns="False" 
       Height="500" 
       AlternationCount="2" 
       FrozenColumnCount="2"> 
     <DataGrid.Columns> 
      <DataGridTextColumn Binding="{Binding Abbreviation}" 
           Header="Abbreviation" /> 
      <DataGridTextColumn Binding="{Binding Title}" 
           Header="Title" /> 

      <DataGridTextColumn Binding="{Binding Fee}" 
           Header="Fee" /> 
      <DataGridTextColumn Binding="{Binding SpecialInstructions}" 
           Header="Special Instructions" /> 
     </DataGrid.Columns> 
    </DataGrid> 

回答

5

什么是在为我工作用这种东西过去,就是在触发器之外使用setter,例如:

<Style TargetType="{x:Type DataGridRow}"> 
    <Style.Triggers> 
     <Trigger Property="IsMouseOver" 
       Value="True"> 
      <Setter Property="Background" 
        Value="Red" /> 
      <Setter Property="FontWeight" 
        Value="ExtraBold" /> 
      <Setter Property="Height" 
        Value="20" /> 
     </Trigger> 
    </Style.Triggers> 
    <Setter Property="AlternatingRowBackground" 
      Value="{DynamicResource AlternatingRow}"/> 
</Style> 

然后他们删除DataGrid本身的属性绑定。尽管我通常使用数据触发器来完成此操作,但通常不使用动态资源绑定。但仍可能值得一拍

+0

你绝对会走向正确的方向。我按照您的建议添加了Setter属性...不是{x:Type DataGridRow},而是{x:Type DataGrid}的单独样式。这就是诀窍。 – 2010-09-01 04:48:38

+0

谢谢!不知道为什么在DataGrid样式中定义AlternatingRowBackground而不是在DataGrid.AlternatingRowBackground中直接允许触发器工作,但我很高兴它! – 2010-10-12 22:47:43

18

有两种方法可以做到这一点,但都不是特别明显。由于DataGridRow将父DataGrid中的背景属性(在代码中)传输到行中的本地值,因此您会注意到它将优先于触发器设置的值。

第一种(也是最简单的)方法是不使用AlternatingRowBackground或RowBackground,而是使用触发器按照Val的建议交替显示背景颜色。他的例子并不完整,不会按原样工作。正确的风格和用法如下。请注意,您需要在DataGrid上设置AlternationCount,否则行将永远不会获得交替索引。

<DataGrid AlternationCount="2"> 
    <DataGrid.RowStyle> 
     <Style TargetType="DataGridRow"> 
      <Setter Property="Background" Value="White"/> 
      <Setter Property="FontWeight" Value="Normal"/> 
      <Style.Triggers> 
       <Trigger Property="AlternationIndex" Value="1"> 
        <Setter Property="Background" Value="Wheat"/> 
        <Setter Property="FontWeight" Value="Bold"/> 
       </Trigger> 
       <Trigger Property="IsMouseOver" Value="True"> 
        <Setter Property="Background" Value="Khaki"/> 
       </Trigger> 
      </Style.Triggers> 
     </Style> 
    </DataGrid.RowStyle> 
</DataGrid> 

第二个选项是使用VisualStateManager。这使您对不同的视觉状态有更多的控制,但它更加冗长。幸运的是,使用Blend复制默认控件模板非常简单。除MouseOver状态中的Storyboard外,以下大部分内容均未更改,并且我已在selectiveScrollingGrid上设置了背景。

对不起,但就像我说的那样,它有点冗长。

<DataGrid AlternationCount="2" AlternatingRowBackground="Wheat"> 
    <DataGrid.RowStyle> 
    <Style TargetType="DataGridRow"> 
     <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="DataGridRow"> 
      <Border x:Name="DGR_Border" 
        Background="{TemplateBinding Background}" 
        BorderBrush="{TemplateBinding BorderBrush}" 
        BorderThickness="{TemplateBinding BorderThickness}" 
        SnapsToDevicePixels="True"> 
       <VisualStateManager.VisualStateGroups> 
       <VisualStateGroup x:Name="CommonStates"> 
        <VisualState x:Name="Normal"/> 
        <VisualState x:Name="Normal_AlternatingRow"/> 
        <VisualState x:Name="Unfocused_Editing"/> 
        <VisualState x:Name="Normal_Editing"/> 
        <VisualState x:Name="Unfocused_Selected"/> 
        <VisualState x:Name="Normal_Selected"/> 
        <VisualState x:Name="MouseOver_Unfocused_Editing"/> 
        <VisualState x:Name="MouseOver_Editing"/> 
        <VisualState x:Name="MouseOver_Unfocused_Selected"/> 
        <VisualState x:Name="MouseOver_Selected"/> 
        <VisualState x:Name="MouseOver"> 
        <Storyboard Storyboard.TargetName="Highlight"> 
         <ColorAnimation Duration="0" Storyboard.TargetProperty="Color" To="Khaki"/> 
        </Storyboard> 
        </VisualState> 
       </VisualStateGroup> 
       </VisualStateManager.VisualStateGroups> 
       <SelectiveScrollingGrid x:Name="selectiveScrollingGrid"> 
       <SelectiveScrollingGrid.Background> 
        <SolidColorBrush x:Name="Highlight" Color="Transparent"/> 
       </SelectiveScrollingGrid.Background> 
       <SelectiveScrollingGrid.ColumnDefinitions> 
        <ColumnDefinition Width="Auto"/> 
        <ColumnDefinition Width="*"/> 
       </SelectiveScrollingGrid.ColumnDefinitions> 
       <SelectiveScrollingGrid.RowDefinitions> 
        <RowDefinition Height="*"/> 
        <RowDefinition Height="Auto"/> 
       </SelectiveScrollingGrid.RowDefinitions> 
       <DataGridCellsPresenter Grid.Column="1" ItemsPanel="{TemplateBinding ItemsPanel}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> 
       <DataGridDetailsPresenter Grid.Column="1" Grid.Row="1" SelectiveScrollingGrid.SelectiveScrollingOrientation="{Binding AreRowDetailsFrozen, ConverterParameter={x:Static SelectiveScrollingOrientation.Vertical}, Converter={x:Static DataGrid.RowDetailsScrollingConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" Visibility="{TemplateBinding DetailsVisibility}"/> 
       <DataGridRowHeader Grid.RowSpan="2" SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical" Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.Row}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/> 
       </SelectiveScrollingGrid> 
      </Border> 
      </ControlTemplate> 
     </Setter.Value> 
     </Setter> 
    </Style> 
    </DataGrid.RowStyle> 
</DataGrid> 
+0

谢谢乔希。我非常喜欢你描述的第一个选项。我希望我能分裂接受的答案。 – 2010-09-01 04:55:49

+0

LOL并不重要,但不应该接受的答案至少编译? :) – Josh 2010-09-01 05:13:13

+1

哈哈!大概是这样的......但是我会觉得残忍地拿走16个声望与17.3k声望的人的答案...... :) – 2010-09-01 05:50:33