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.