2010-09-01 2 views
11

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

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

Update: Вот правильный синтаксис, основанный на @ руководство Вэл:

<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

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

<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: Тип DataGridRow}, а как отдельный стиль для {x: Тип DataGrid}. Это делает трюк. –

+0

Спасибо! Не уверен, почему определение AlternatingRowBackground в стиле DataGrid, а не в DataGrid.AlternatingRowBackground напрямую позволяет триггеру работать, но я рад, что это так! –

18

Существует два способа сделать это, и это не особенно очевидно. Поскольку DataGridRow передает (в коде) свойство background из родительского 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, и я установил фон в 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

Спасибо, Джош.Мне очень нравится первый вариант, который вы описываете. Хотел бы я расколоть принятый ответ. –

+0

LOL действительно не имеет значения, но не должен ли принятый ответ хотя бы скомпилировать? :) – Josh

+1

Ха-ха! Наверное, так ... но я бы чувствовал себя жестоким, отнимая ответ от кого-то с 16-ю репутацией против вашего 17.3k ... :) –

Смежные вопросы