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

孤街浪徒 提交于 2020-01-04 13:28:26

问题


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?


回答1:


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;
    }        
}



回答2:


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



来源:https://stackoverflow.com/questions/3970363/silverlight-datagrid-highlight-an-entire-column-when-that-column-is-sorted

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!