如果对DataGrid列进行排序(而不是排序),如何通知我

时间:2011-12-07 14:29:57

标签: .net wpf sorting datagrid

我需要为WPF应用程序中的DataGrid提供Sorted事件,但无法找到获取它的方法。

以下是我的尝试:

DataGrid提供了一个事件Sorting,但我无法使用它,因为它在排序完成之前被触发了。 EventArgs给我一个已排序的列但不是它的排序方式,如果我得到排序方向,它将被设置为旧值。当然我可以猜到它会是什么,因为我知道它会从无翻转到提升并最终降级但是这将无法解决,因为如果控件的行为发生变化,它将失败。

第二次尝试:

DataGrid有一个默认视图,可以访问SortDescriptionCollection。此集合包含所有排序属性,但我认为没有任何可能让我通知更改。

我不得不说我正在寻找一个尽可能干净的解决方案,因为它将用于一个大型项目,在这个项目中我无法使用在环境发生变化时可能会失败的解决方案。

有没有人从经验(或文档?)中知道如何解决这个问题?

编辑:为了更清楚地说明我想要实现的目标:我需要了解当用户对列进行排序时,DataGrid列在哪个方向排序。排序本身之后没有必要提供这些信息,只需要正确;)

3 个答案:

答案 0 :(得分:14)

我自己通过覆盖DataGrid实现了DataGrid事件的Sorted,如下所示:

public class ValueEventArgs<T> : EventArgs
{
    public ValueEventArgs(T value)
    {
        Value = value;
    }

    public T Value { get; set; }

}

public class DataGridExt : DataGrid
{
    public event EventHandler<ValueEventArgs<DataGridColumn>> Sorted;

    protected override void OnSorting(DataGridSortingEventArgs eventArgs)
    {
        base.OnSorting(eventArgs);

        if (Sorted == null) return;
        var column = eventArgs.Column;
        Sorted(this, new ValueEventArgs<DataGridColumn>(column));
    }
}

为了使用它,您需要做的就是:

    private void Initialize()
    {
            myGrid.Sorted += OnSorted;
    }
    private void OnSorted(object sender, ValueEventArgs<DataGridColumn> valueEventArgs)
    {
    // Persist Sort...
    }

答案 1 :(得分:1)

我无法让Stephen Lautier的解决方案在VB.Net中工作,但我找到了另一种可行的解决方案。

每当发生排序操作时,以列出的顺序发生以下事件:

  1. 排序
  2. UnloadingRow(对于DataGrid中的所有行)
  3. LoadingRow(对于DataGrid中的所有行)
  4. LayoutUpdated
  5. 这可以通过以下方式使用:

    <强>变量

    Private _updateSorted As Boolean
    Private _tempSender As Object
    Private _rowsLoaded As List(Of DataGridRowEventArgs)
    _rowsLoaded = New List(Of DataGridRowEventArgs)
    

    <强>分拣

    Private Sub myDataGrid_Sorting(sender As Object, e As DataGridSortingEventArgs) Handles myDataGrid.Sorting
        _updateSorted = True
        _rowsLoaded.Clear()
        _tempSender = Nothing
    End Sub
    

    卸载行/加载行事件

    'Save pre-sorting state here, if desired'
    'Perform operation on pre-sorting rows here, if desired'
    Private Sub myDataGrid_UnloadingRow(sender As Object, e As DataGridRowEventArgs) Handles myDataGrid.UnloadingRow
    
    End Sub
    
    'Save post-sorting state here.'
    'Perform operation on post-sorting rows here'
    'In this example, the operation is dependent on the DataGrid updating its layout first so I included items relevant to handling that'
    Private Sub myDataGrid_LoadingRow(sender As Object, e As DataGridRowEventArgs) Handles myDataGrid.LoadingRow
        Dim myDataGridCell As DataGridCell = GetCellByRowColumnIndex(myDataGrid, e.Row.GetIndex, colIndex)  
        'Or whatever layout-dependent object you are using, perhaps utilizing e As DataGridRowEventArgs'
    
            If Not IsNothing(myDataGridCell) Then
               '~~ Perform operations here ~~'
            Else
                If _updateSorted Then
                    'Update has occurred but the updated DataGrid is not yet available'
                    'Save variables to use once the DataGrid is updated'
                    _rowsLoaded.Add(e)
                    _tempSender = sender
                End If
            End If
    End Sub
    

    <强> LayoutUpdated

    Private Sub myDataGrid_LayoutUpdated(sender As Object, e As EventArgs) Handles myDataGrid.LayoutUpdated
        If _updateSorted Then
            Dim rowsLoaded As New List(Of DataGridRowEventArgs)
            For Each eRow As DataGridRowEventArgs In _rowsLoaded
                rowsLoaded.Add(eRow)
            Next
    
            For Each eRow As DataGridRowEventArgs In rowsLoaded
                'Now perform the action to the sorted DataGridRows in the order they were added'
                myDataGrid_LoadingRow(_tempSender, eRow)
            Next
            _updateSorted = False
        End If
    End Sub
    

答案 2 :(得分:0)

经过几个小时的尝试和阅读后,我能够自己解决问题。我对解决方案并不十分满意,但它对我有用。

由于我要按代码生成DataGrid列,我可以使用每列的DependencyProperty SortDirection并添加一个方法,该属性将在属性更改时调用。这样做是这样的:

DataGridBoundColumn column = GetTheColumnIWantToObserve();
if (column != null)
{
    // add value changed notification to be informed about changes
    var desc = DependencyPropertyDescriptor.FromProperty(DataGridColumn.SortDirectionProperty, typeof(DataGridColumn));
    desc.AddValueChanged(column, ColumnSortDirectionChanged);
}

在方法ColumnSortDirectionChanged中,我现在可以处理更改。

private void ColumnSortDirectionChanged(object sender, EventArgs eventArgs)
{
    var column = sender as DataGridColumn;
    if (column != null)
    {
        var newSortDirection = column.SortDirection;
        // Yay, I got it!!
    }
}

如果我不自行生成列,则必须使用DataGrid事件(例如LoadedAutoGeneratedColumns)并将通知添加到所有现有列。