How can I get notifications if I sort a DataGrid column (rather than sort)

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

Here is what I tried:

DataGrid provides a Sorting event, but I cannot use it because it is fired before sorting is done. EventArgs give me a column that 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 that it would be, as I know, that it would turn from none to upstream and finally to downward, but this would not be a solution, as it would fail if the behavior of the control changes.

Second attempt:

DataGrid has a default view that provides access to the SortDescriptionCollection . This collection contains all the sorting properties, but I see no way to let me know about the changes.

I have to say that I am looking for a solution as clean as possible, as it will be used in a large project where I cannot use solutions that can fail if the environment changes.

Does anyone know from experience (or documentation?) How I can solve this problem?

Edit: In order to more clearly understand what I want to achieve: I need to find out which DataGrid column is sorted in the direction when the user sorts the column. There is no need for this information to come after the sorting itself, it must be correct;)

+5
source share
3 answers

I implemented the Sorted for the DataGrid event, 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)); } } 

To use it, all you have to do is the following:

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

I could not get the Stephen Lautier solution to work on VB.Net, but found another solution that might work.

Whenever a sort operation occurs, the following events occur in that order:

  • Sorting
  • UnloadingRow (for all rows in a DataGrid)
  • Loading Row (for all rows in a DataGrid)
  • Layoutupdated

This can be used as follows:

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 

Upload / Download Event Strings

 '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 
+1
source

After many hours of trying and reading, I was able to solve the problem myself. I am not completely satisfied with the solution, but it works for me.

Since I allow the generation of DataGrid columns by code, I could use the DependencyProperty SortDirection each column and add a method that will be called when the property changes. This is done as follows:

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

In the ColumnSortDirectionChanged method, I can now work with the changes.

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

If I hadn’t generated the columns myself, I would have to use the DataGrid event (for example, Loaded or AutoGeneratedColumns ) and add a notification to all existing columns.

0
source

All Articles