我需要为WPF应用程序中的DataGrid
提供Sorted
事件,但无法找到获取它的方法。
以下是我的尝试:
DataGrid
提供了一个事件Sorting
,但我无法使用它,因为它在排序完成之前被触发了。 EventArgs
给我一个已排序的列但不是它的排序方式,如果我得到排序方向,它将被设置为旧值。当然我可以猜到它会是什么,因为我知道它会从无翻转到提升并最终降级但是这将无法解决,因为如果控件的行为发生变化,它将失败。
第二次尝试:
DataGrid
有一个默认视图,可以访问SortDescriptionCollection
。此集合包含所有排序属性,但我认为没有任何可能让我通知更改。
我不得不说我正在寻找一个尽可能干净的解决方案,因为它将用于一个大型项目,在这个项目中我无法使用在环境发生变化时可能会失败的解决方案。
有没有人从经验(或文档?)中知道如何解决这个问题?
编辑:为了更清楚地说明我想要实现的目标:我需要了解当用户对列进行排序时,DataGrid
列在哪个方向排序。排序本身之后没有必要提供这些信息,只需要正确;)
答案 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中工作,但我找到了另一种可行的解决方案。
每当发生排序操作时,以列出的顺序发生以下事件:
这可以通过以下方式使用:
<强>变量强>
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
事件(例如Loaded
或AutoGeneratedColumns
)并将通知添加到所有现有列。