Highlighting entire column in Datagrid
I came across this post on stackoverflow on highlighting an entire column when that column is sorted (clicked on header). The question was already answered. Here is another version. ItemsSource property need not be a PagedCollectionView in this version. The code need to be changed if there are any TemplateColumns defined.
using this behavior
<sdk:DataGrid x:Name=”datagrid1″ >
<i:Interaction.Behaviors>
<local:HiliteColumnBehavior/>
</i:Interaction.Behaviors>
</sdk:DataGrid>
Here is the behavior itself
public class HiliteColumnBehavior : Behavior<DataGrid>
{
bool isDragging = false;
bool isDone = false;
readonly SolidColorBrush hiliteColor = new SolidColorBrush(Colors.LightGray);
readonly SolidColorBrush normalColor = new SolidColorBrush(Colors.White);
DataGridColumnHeader currentSortColumnHeader;
ScrollBar scrollbar;
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.ColumnHeaderDragStarted += new EventHandler<DragStartedEventArgs>(AssociatedObject_ColumnHeaderDragStarted);
AssociatedObject.ColumnHeaderDragCompleted += new EventHandler<DragCompletedEventArgs>(AssociatedObject_ColumnHeaderDragCompleted);
AssociatedObject.LayoutUpdated += new EventHandler(AssociatedObject_LayoutUpdated);
AssociatedObject.SizeChanged += (s, e) => { Hilite(); };
}
DataGridColumnHeadersPresenter dchp;
void AssociatedObject_LayoutUpdated(object sender, EventArgs e)
{
dchp = AssociatedObject.GetChildrenByType<DataGridColumnHeadersPresenter>().FirstOrDefault();
if (dchp != null && !isDone) {
foreach (DataGridColumnHeader dgch in dchp.Children)
dgch.AddHandler(DataGridColumnHeader.MouseLeftButtonUpEvent, new MouseButtonEventHandler(header_MouseLeftButtonUp), true);
isDone = true;
}
if (scrollbar == null)
{
scrollbar = AssociatedObject.GetChildrenByType<ScrollBar>().FirstOrDefault();
scrollbar.Scroll += new ScrollEventHandler(scrollbar_Scroll);
}
}
void scrollbar_Scroll(object sender, ScrollEventArgs e)
{
if (e.ScrollEventType == ScrollEventType.EndScroll)
Hilite();
}
void AssociatedObject_ColumnHeaderDragCompleted(object sender, DragCompletedEventArgs e)
{
isDragging = false;
}
void AssociatedObject_ColumnHeaderDragStarted(object sender, DragStartedEventArgs e)
{
isDragging = true;
}
void header_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
currentSortColumnHeader = sender as DataGridColumnHeader;
if (!isDragging)
{
Hilite();
}
}
private void Hilite()
{
if (currentSortColumnHeader == null)
return;
int columnIndex = dchp.Children.IndexOf(currentSortColumnHeader);
List<DataGridRow> rows = AssociatedObject.GetChildrenByType<DataGridRow>();
rows.ForEach(x => { x.GetChildrenByType<DataGridCell>().Where((y, i) => i == columnIndex).ToList().ForEach(z => z.Background = hiliteColor); });
rows.ForEach(x => { x.GetChildrenByType<DataGridCell>().Where((y, i) => i != columnIndex).ToList().ForEach(z => z.Background = normalColor); });
}
protected override void OnDetaching()
{
base.OnDetaching();
foreach (DataGridColumnHeader dgch in dchp.Children)
dgch.RemoveHandler(DataGridColumnHeader.MouseLeftButtonUpEvent, new MouseButtonEventHandler(header_MouseLeftButtonUp));
if (scrollbar != null)
{
scrollbar.Scroll -= new ScrollEventHandler(scrollbar_Scroll);
}
}
}
public static class Extensions
{
public static T FindParentOfType<T>(this FrameworkElement element)
{
if (element == null)
return default(T);
var parent = VisualTreeHelper.GetParent(element) as FrameworkElement;
while (parent != null)
{
if (parent is T)
return (T)(object)parent;
parent = VisualTreeHelper.GetParent(parent) as FrameworkElement;
}
return default(T);
}
// Methods
public static List<T> GetChildrenByType<T>(this UIElement element) where T : UIElement
{
return element.GetChildrenByType<T>(null);
}
public static List<T> GetChildrenByType<T>(this UIElement element, Func<T, bool> condition) where T : UIElement
{
List<T> results = new List<T>();
GetChildrenByType<T>(element, condition, results);
return results;
}
private static void GetChildrenByType<T>(UIElement element, Func<T, bool> condition, List<T> results) where T : UIElement
{
if (element == null)
return;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++)
{
UIElement child = VisualTreeHelper.GetChild(element, i) as UIElement;
if (child != null)
{
T t = child as T;
if (t != null)
{
if (condition == null)
{
results.Add(t);
}
else if (condition(t))
{
results.Add(t);
}
}
GetChildrenByType<T>(child, condition, results);
}
}
}
public static bool HasChildrenByType<T>(this UIElement element, Func<T, bool> condition) where T : UIElement
{
return (element.GetChildrenByType<T>(condition).Count != 0);
}
}