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

Spa*_*k13 0 wpf xaml datagrid

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

Xml:

<DataGrid Name="List" SortStart="List_sortStart" SortComplete="sortComplete" />
Run Code Online (Sandbox Code Playgroud)

xml文件

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

void List_sortComplete(object sender, EventArgs e) {
    this.Cursor = Cursors.Arrow;
}
Run Code Online (Sandbox Code Playgroud)

但是 DataGrid 没有 SortStart 和 SortComplete 事件。

dap*_*api 5

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

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

private static readonly Dispatcher UIDispatcher = Dispatcher.CurrentDispatcher;
Run Code Online (Sandbox Code Playgroud)

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

<DataGrid ... Sorting="DataGrid_Sorting">
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

Mouse.OverrideCursor = null;
Run Code Online (Sandbox Code Playgroud)

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

就是这样。在为 WPF 编码时,这个“技巧”在很多情况下都很有用。把它放在你的箭袋里。