How can I be notified if a DataGrid column is sorted (and not sorting)

10,570

Solution 1

I implemented the Sorted for the DataGrid event myself by overriding the DataGrid as follows:

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

In order to use it then all you need to do is this:

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

Solution 2

I could not get Stephen Lautier's solution to work in VB.Net, but I found another solution that can work.

Whenever a sorting operation occurs, the following events occur in the listed order:

  1. Sorting
  2. UnloadingRow (For all rows in the DataGrid)
  3. LoadingRow (For all rows in the DataGrid)
  4. LayoutUpdated

This can be utilized in the following way:

Variables

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

Sorting

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

UnloadingRow/Loading Row Events

'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
Share:
10,570

Related videos on Youtube

MatthiasG
Author by

MatthiasG

As a software developer working in .NET related projects I'm interested in many related things, too.

Updated on June 04, 2022

Comments

  • MatthiasG
    MatthiasG about 2 years

    I need to have kind of an Sorted event for a DataGrid in a WPF application but cannot find a way to get it.

    Here is what I tried:

    The DataGrid provides an event Sorting, but I cannot use it as it is fired before the sorting is done. The EventArgs give me the column which is sorted but not the way it is sorted and if I get the sort direction it is set to the old value. Of course I could guess what it will be as I know that it flips from none to ascending and finally to descending but that would be no solution as it would fail if the behavior of the control changes.

    Second try:

    The DataGrid has a default view which provides access to a SortDescriptionCollection. This collection holds all sorting properties but I don't see any possibility to let me inform about changes.

    I have to say that I'm looking for a solution as clean as possible as it will be used in a large project on which I can't use solutions which could fail if the environment changes.

    Does anyone know from experience (or documentation?) how I could solve this problem?

    Edit: To make more clear what I want to achieve: I need to get informed which DataGrid column is sorted in which direction when a user sort a column. It is not necessary that this information comes after the sorting itself, it just has to be correct ;)

  • Houman
    Houman over 12 years
    Thats indeed a such a god solution. The SortDirection changes the moment you click on Sort. The actual sorting might take much longer, you have no guarantee that your solution kicks in exactly after the Sort has finished.
  • MatthiasG
    MatthiasG over 12 years
    So you've another idea? For me this is fine as I use the information to store it in a configuration file for the next application start. The timing doesn't matter that much. Nethertheless, as I wrote, I'm not completly satisfied with this, so I'd be happy about suggestions.
  • Mal Ross
    Mal Ross about 8 years
    Where did you find the information about the order of events? I'm trying to use the LayoutUpdated event (when preceded by a Sorting event) as my trigger to scroll the datagrid to the top. While all relevant calls appear to be executing as intended, the final behaviour isn't happening - my datagrid isn't scrolling to the top after a sort. Instead, it's keeping the selected row in view.
  • PellucidWombat
    PellucidWombat about 8 years
    I wish I knew of a reference source, but I don't! Instead I did some experimenting. Basically, in these scenarios I try creating various events that are either what I think I want or are relevant. I then have the event listener send an informative message to the console. That way, reporting doesn't interfere with using the GUI, and the messages let me know that a particular event fired. Through trial and error I can get a picture of the firing order, frequency, patterns, or how consistent it might be with different setups and actions.
  • PellucidWombat
    PellucidWombat about 8 years
    Your situation sounds like it is dependent on certain options you have set in the datagrid or related code, such as automatically scrolling to selection. So if that isn't what you want, I'd look into how your selection is maintained or reset after initiating a sort. This can give you a clue as to where/how to change the behavior.