Триггер стиля WPF для цвета фона DataGridRow превзойден кистью AlternatingRowBackground - PullRequest
11 голосов
/ 01 сентября 2010

У меня есть WPF DataGrid с кистью AlternatingRowBackground.Он настроен на цвет каждого второго ряда.Я хотел бы сделать что-то на мышь, чтобы выделить текущий ряд.Тем не менее, кажется, что Style Trigger проигрывает кисти AlternatingRowBackground.Я получаю желаемую окраску строки при наведении мыши ... но только на строки, которые не закрашены кистью AlternatingRowBackground.

Вот стиль в Windows.* А вот 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 выигрывает, потому что она напрямую связана с наиболее определенной частью объявления.

Обновление: Вот правильный синтаксис, основанный на руководстве @ 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 ]

18 голосов
/ 01 сентября 2010

Есть два способа сделать это, ни один не особенно очевиден. Поскольку DataGridRow передает (в коде) свойство фона из родительского DataGrid в локальное значение в строке, как вы заметили, оно будет иметь приоритет над значением, установленным вашим триггером.

Первый (и самый простой) способ - не использовать AlternatingRowBackground или RowBackground, а использовать триггеры для чередования цвета фона, как предложил Val. Его пример не завершен, хотя и не будет работать как есть. Правильный стиль и использование будет следующим. Обратите внимание, что вам нужно установить AlternationCount в DataGrid, иначе строки никогда не получат чередующиеся индексы.

<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, и я установил фон для selectedScrollingGrid.

Извините за завертывание, но, как я уже сказал, это немного более многословно.

<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>
5 голосов
/ 01 сентября 2010

То, что раньше работало для меня с такими вещами, - это использование сеттера вне триггеров, например:

<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.Хотя я обычно делаю это с триггерами данных, а не с динамическими привязками ресурсов.Но все же может стоить выстрел

...