开发者

Silverlight Datagrid: Highlight an entire column when that column is sorted

I have a DataGrid in my Silverlight application that I would like to highlight an entire column when that co开发者_运维百科lumn 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/

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜