c# – Silverlight Datagrid: Highlight an entire column when that column is sorted – Education Career Blog

I have a DataGrid in my Silverlight application that I would like to highlight an entire column when that column is sorted.

It’s similar in concept to this previous question: Silverlight DataGrid: Highlight an entire column.

Any ideas? I’ve thought maybe attaching a behavior to the LayoutUpdated event and checking a cell to see if it’s in a sorted column?

,

There are several issues that you have to get around to do what you want to do. The biggest issue is that finding out when a column is sorted is a lot harder then it should be. The only way I have ever found to identify that a column was sorted to make DataGrid.ItemsSource a PagedCollectionView and listen to the CollectionChanged event on its SortDescriptions property. If you use a PagedCollectionView for your ItemsSource and all columns that can be sorted on are DataGridBoundColumn (really any of the premades other than TemplateColumn) then this behavior should be fairly close to what you want to do.

public class DataGridSortedColumnHighlightBehavior : Behavior<DataGrid>
{

    private List<DataGridRow> rows = new List<DataGridRow>();

    protected override void OnAttached()
    {
        base.OnAttached();

        AssociatedObject.LoadingRow += AssociatedObject_LoadingRow;
        AssociatedObject.UnloadingRow += AssociatedObject_UnloadingRow;

        if (AssociatedObject.ItemsSource == null)
        {
            AssociatedObject.LayoutUpdated += AssociatedObject_LayoutUpdated;
        }
        else
        {
            var collection =
                ((AssociatedObject.ItemsSource as PagedCollectionView).SortDescriptions as INotifyCollectionChanged);
            collection.CollectionChanged += DataGridSortedColumnHighlightBehavior_CollectionChanged;
        }
    }

    void AssociatedObject_UnloadingRow(object sender, DataGridRowEventArgs e)
    {
        rows.Remove(e.Row);
    }

    void AssociatedObject_LoadingRow(object sender, DataGridRowEventArgs e)
    {
        rows.Add(e.Row);
    }

    private void AssociatedObject_LayoutUpdated(object sender, EventArgs e)
    {
        if (AssociatedObject.ItemsSource != null)
        {
            AssociatedObject.LayoutUpdated -= AssociatedObject_LayoutUpdated;
            var collection =
                ((AssociatedObject.ItemsSource as PagedCollectionView).SortDescriptions as INotifyCollectionChanged);
            collection.CollectionChanged += DataGridSortedColumnHighlightBehavior_CollectionChanged;
        }
    }

    void DataGridSortedColumnHighlightBehavior_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if(e.NewItems != null)
        {
            foreach(SortDescription sortDesc in e.NewItems)
            {
                foreach(var column in AssociatedObject.Columns)
                {
                    var boundColumn = column as DataGridBoundColumn;
                    if (boundColumn == null)
                        continue;
                    if (boundColumn.Binding.Path.Path == sortDesc.PropertyName)
                    {
                        foreach (var row in rows)
                            ColorCell(column,row,Colors.Red);
                    }
                }
            }
        }
        if(e.OldItems != null)
        {
            foreach(SortDescription sortDesc in e.OldItems)
            {
                foreach(var column in AssociatedObject.Columns)
                {
                    var boundColumn = column as DataGridBoundColumn;
                    if (boundColumn == null)
                        continue;
                    if (boundColumn.Binding.Path.Path == sortDesc.PropertyName)
                    {
                        foreach (var row in rows)
                            ColorCell(column,row,Colors.White);
                    }
                }
            }
        }
    }

    private void ColorCell(DataGridColumn column, DataGridRow item, Color color )
    {
        var content = column.GetCellContent(item);
        if (content == null)
            return;

        var parent = GetParent<DataGridCell>(content);

        if (parent != null)
            parent.Background = new SolidColorBrush(color);

    }

    public static T GetParent<T>(DependencyObject source)
        where T : DependencyObject
    {
        DependencyObject parent = VisualTreeHelper.GetParent(source);
        while (parent != null && !typeof(T).IsAssignableFrom(parent.GetType()))
        {
            parent = VisualTreeHelper.GetParent(parent);
        }
        return (T)parent;
    }        
}

,

Here is another way
http://leeontech.wordpress.com/2010/10/20/highlighting-entire-column-in-datagrid/

Leave a Comment