代码之家  ›  专栏  ›  技术社区  ›  Mike L

DataGridRow背景色的WPF样式触发器被AlternatingRowBackground笔刷覆盖

  •  11
  • Mike L  · 技术社区  · 16 年前

    这是我的风格Windows资源:

    <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 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刷胜出是因为它与声明的最具体部分直接相关。

    更新: 以下是基于@Val指导的正确语法:

    <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>
    
    2 回复  |  直到 16 年前
        1
  •  5
  •   Val    16 年前

    在过去,对我来说,在触发器之外使用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 它自己。尽管我通常是用数据触发器来实现的,而不是用动态资源绑定。但还是值得一试

        2
  •  20
  •   Josh    16 年前

    有两种方法可以做到这一点,都不是特别明显。因为DataGridRow(在代码中)将background属性从父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复制默认控件模板非常容易。除了鼠标悬停状态下的情节提要外,下面的大部分内容都没有改变,我在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>