Home > database >  Change DataGridColumnheader background on click of DatagridCell or current cell changed
Change DataGridColumnheader background on click of DatagridCell or current cell changed

Time:07-15

The background of the column header of the current cell is changed when the CurrentCellChanged event is raised using this code in code-behind:

private void DataGrid_CurrentCellChanged(object sender, EventArgs e)
{
   foreach (var item in dataGrid.Columns)
   {
       if (item.HeaderStyle != null)
       {
           item.HeaderStyle = null;
       }
   }
   Style selectedColumnStyle = new Style(typeof(DataGridColumnHeader));
   selectedColumnStyle.Setters.Add(new Setter(DataGridColumnHeader.BackgroundProperty, Brushes.Gray));
   dataGrid.Columns[Index].HeaderStyle = selectedColumnStyle;
}

How to achieve same functionality in XAML using a style and triggers ?

CodePudding user response:

I do not think that you can achieve this purely in XAML...but almost. You could create a column header style that changes the background, which is triggered by determining if the current cell column matches the column of the header that the style is applied to.

<DataGrid ...>
   <DataGrid.Resources>
      <local:EqualityToBoolConverter x:Key="EqualityToBoolConverter"/>
   </DataGrid.Resources>
   <DataGrid.ColumnHeaderStyle>
      <Style TargetType="{x:Type DataGridColumnHeader}" BasedOn="{StaticResource {x:Type DataGridColumnHeader}}">
         <Style.Triggers>
            <DataTrigger Value="True">
               <DataTrigger.Binding>
                  <MultiBinding Converter="{StaticResource EqualityToBoolConverter}">
                     <Binding RelativeSource="{RelativeSource Self}" Path="Column"/>
                     <Binding RelativeSource="{RelativeSource AncestorType={x:Type DataGrid}}" Path="CurrentCell.Column"/>
                  </MultiBinding>
               </DataTrigger.Binding>
               <Setter  Property="Background" Value="Gray"/>
            </DataTrigger>
         </Style.Triggers>
      </Style>
   </DataGrid.ColumnHeaderStyle>
 
   <!-- ...your markup. -->

</DataGrid>

As you can see, there is a multi binding that binds the column of the header the style is applied to and the column of the current cell. What we still need in code is a converter that checks for equality.

public class EqualityToBoolConverter : IMultiValueConverter
{
   public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
   {
      return values != null && values.Length > 0 && values.Skip(1).All(value => Equals(values[0], value));
   }

   public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
   {
      throw new InvalidOperationException("This conversion is one-way.");
   }
}

The DataTrigger then receives a boolean indicating, whether to apply the setters or not.

  • Related