2010-09-01 12 views
11

Tengo un WPF DataGrid que tiene un pincel AlternatingRowBackground. Está configurado para colorear cada dos filas. Me gustaría hacer algo sobre el mouse que resalte la fila actual. Sin embargo, el disparador de estilo parece estar perdiendo en el pincel AlternatingRowBackground. Obtengo la coloración de fila deseada sobre el mouse ... pero solo en las filas que no están pintadas con el pincel AlternatingRowBackground.Disparador de estilo WPF para DataGridRow Color de fondo superado por AlternatingRowBackground Brush

Aquí es el estilo en 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> 

Y aquí es la cuadrícula de datos:

<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> 

¿Hay una manera de declarar el ganador absoluto? ¿Es el problema uno de una jerarquía? Me parece que el pincel AlternatingRowBackground gana porque está directamente asociado con la parte más específica de la declaración.

Actualización: Aquí se muestra la sintaxis correcta, en base a @ orientación del 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> 

Y la cuadrícula de datos (menos el cepillo 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> 

Respuesta

5

lo que ha funcionado para mí en el pasado con este tipo de cosas, es utilizar un colocador fuera de los factores desencadenantes, por ejemplo:

<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> 

Y ellos eliminan la propiedad vinculante en el DataGrid sí mismo. Aunque generalmente hago esto con desencadenadores de datos, y normalmente no con enlaces de recursos dinámicos. Pero aún podría valer la pena intentarlo

+0

definitivamente estoy yendo en la dirección correcta. Agregué la propiedad Setter como sugirió ... no al {x: Type DataGridRow}, sino como un estilo separado para {x: Type DataGrid}. Eso hace el truco. –

+0

¡Gracias! No estoy seguro de por qué la definición de AlternatingRowBackground en un estilo DataGrid en lugar de en DataGrid.AlternatingRowBackground permite que el desencadenador funcione, pero me alegro de que lo haga. –

18

Hay dos formas de hacerlo, ninguna de las dos es particularmente obvia. Dado que DataGridRow transfiere (en código) la propiedad de fondo del DataGrid padre a un valor local en la fila, como ha notado, tendrá prioridad sobre el valor establecido por su activador.

La primera (y la más simple) forma es no usar AlternatingRowBackground o RowBackground, sino usar activadores para alternar el color de fondo como Val sugiere. Sin embargo, su ejemplo no está completo y no funcionará tal como está. El estilo y el uso correctos serían los siguientes. Tenga en cuenta que debe establecer AlternationCount en DataGrid o, de lo contrario, las filas nunca obtendrán índices alternados.

<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> 

La segunda opción es usar el VisualStateManager. Esto le da mucho más control sobre los diferentes estados visuales, pero es más detallado. Afortunadamente, es bastante fácil copiar la plantilla de control predeterminada con Blend. La mayoría de los siguientes no han cambiado excepto Storyboard en el estado MouseOver y he establecido un fondo en selectScrollingGrid.

Perdón por el abrigo, pero como he dicho, es un poco más detallado.

<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

Gracias Josh.Me gusta mucho la primera opción que describes. Desearía poder dividir la respuesta aceptada. –

+0

LOL en realidad no importa, pero ¿no debería al menos compilar la respuesta aceptada? :) – Josh

+1

¡Ja ja! Probablemente sea así ... pero me sentiría cruel arrebatarle la respuesta a alguien con una reputación de 16 frente a los 17.3k ... :) –

Cuestiones relacionadas