如何在排序DataGrid时更改光标?

时间:2015-04-13 07:03:50

标签: wpf xaml datagrid

当DataGrid(wpf)有很多行时,排序可能需要很长时间(最多5-10秒)。如何在搜索时将光标更改为Cursors.Wait? 我需要这样的事情:

的Xaml:

<DataGrid Name="List" SortStart="List_sortStart" SortComplete="sortComplete" />

Xaml.cs

void List_sortStart(object sender, EventArgs e) {
    this.Cursor = Cursors.Wait;
}

void List_sortComplete(object sender, EventArgs e) {
    this.Cursor = Cursors.Arrow;
}

但是DataGrid没有SortStart和SortComplete事件。

2 个答案:

答案 0 :(得分:4)

问题在于WPF /渲染架构在处理用户界面更新时缺乏确定性;在这种情况下,DataGrid排序更改。 DataGrid排序操作通过鼠标单击该列开始,然后单击该列,然后更新CollectionView,最终在稍后的某个时间点在DataGrid中呈现。要根据需要更改鼠标光标,需要在排序操作开始时将光标更改为忙碌光标,然后将更改推迟到正常光标,直到用户界面上下文完成时的时间点最终的布局工作。幸运的是这是可能的!

首先,需要引用主渲染线程的调度程序。获取它的一种简单方法是创建一个类级数据项(在代码隐藏.CS文件中),由主用户界面线程初始化:

private static readonly Dispatcher UIDispatcher = Dispatcher.CurrentDispatcher;

接下来,(在XAML中)引用DataGrid排序事件的代码隐藏处理程序,该事件在排序操作开始时执行:

<DataGrid ... Sorting="DataGrid_Sorting">

代码隐藏文件中的处理程序如下所示:

private void DataGrid_Sorting(object sender, DataGridSortingEventArgs e)
{
    Mouse.OverrideCursor = Cursors.Wait;
    UIDispatcher.BeginInvoke((System.Action) (() => { Mouse.OverrideCursor = null; }),
                             DispatcherPriority.ContextIdle);
}

注意上面代码中的几个部分。首先,当排序操作开始时,我们用第一行上的等待动画光标覆盖鼠标光标。接下来,我们使用 DispatcherPriority.ContextIdle 优先级安排在用户界面调度程序上执行的代码。这是推迟代码将鼠标光标恢复正常的秘诀。

将鼠标光标更改回正常的代码:

Mouse.OverrideCursor = null;

仅在用户界面调度程序完成排序更改/布局更新逻辑的所有处理之后执行,然后变为空闲&#34;。

就是这样。这个&#34;技巧&#34;在编写WPF时,在许多情况下都很有用。把它放在你的箭袋里。

答案 1 :(得分:1)

DataGrid发生Sorting事件,该事件将在排序即将开始时发生。您可以将List_sortStart方法附加到此活动。

但问题来了,据我所知,DataGrid在排序完成时没有发生事件。解决此限制的一种可能方法是使用一种排序已完成事件创建自定义DataGrid,请参阅this other SO post中的示例:

<local:DataGridExt Name="List" Sorting="List_sortStart" Sorted="List_sortComplete" />