UI响应性并使用WPF中的“SelectedItem”ListView / ListBox
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UI响应性并使用WPF中的“SelectedItem”ListView / ListBox相关的知识,希望对你有一定的参考价值。
我有一些情况,我试图设计我的WPF .NET 4.0应用程序来处理ListBox / ListView中的SelectedItem的更改。
基本上我想查询其他数据以根据用户选择的内容填充ObservableCollection / DataGrid。我的问题是,通过将所有内容放在同一个线程上,响应性会受到影响,因为单击的项目仅在“SelectedItem”Setter中启动的任何代码完成时显示为选中,并且此“等待”不响应我的方式想要它。
正在查询的数据通常通过LINQ从同一个数据库填充ObservableCollection,这就是为什么一切都使用相同的UI线程。
理想情况下我想:
- 用户单击列表中的项目,该项目立即被选中,而不会感觉应用程序挂起。
- 要将“IsBusy”属性设置为true(用于绑定以更改某些控件的启用状态)。
- 开始查询其他数据并完成该操作后,应填充(例如)DataGrid,并将IsBusy返回false。
在“后台”中加载辅助数据来实现此目的的最佳方法是什么?我以前在WinForms中使用过BackgroundWorker,但我很想了解更多有关Dispatcher的信息,我认为这是正确的方向。
我的SelectedItem属性和这一样简单:
public Employee SelectedEmployee
{
get
{
return mvSelectedEmployee;
}
set
{
mvSelectedEmployee = value;
RaisePropertyChanged();
IsBusy = true;
QueryMyEmployeesAddressesAndOtherData(); //which takes sometimes 2 seconds
IsBusy = false;
}
}
我希望用户知道某些事情正在发生,但尽管有一点点延迟。
谢谢。
使用async / await是实现此目的的最佳方法。您的特定情况的一个问题是属性设置器不能标记为async
。但是,你可以从二传手中开出一个async void
方法。这是一个简单的示例,无需更改代码库中的任何其他内容即可使用:
public Employee SelectedEmployee
{
get
{
return mvSelectedEmployee;
}
set
{
mvSelectedEmployee = value;
RaisePropertyChanged();
UpdateSelectedEmployeeAsync();
}
}
private async void UpdateSelectedEmployeeAsync()
{
IsBusy = true;
await Task.Run(() => QueryMyEmployeesAddressesAndOtherData());
IsBusy = false;
}
但是你真正想要做的就是让QueryMyEmployeesAddressesAndOtherData
异步“一直向下”。 Task.Run
实际上更适合在后台运行CPU绑定操作,但听起来你的主要是IO绑定(等待一些查询执行)。无论您使用什么持久性框架,都很可能具有异步支持(如果不支持,请考虑更新为支持框架)。现在你可能最终得到这样的东西:
private async void UpdateSelectedEmployeeAsync()
{
IsBusy = true;
await QueryMyEmployeesAddressesAndOtherDataAsync();
IsBusy = false;
}
private async Task QueryMyEmployeesAddressesAndOtherDataAsync()
{
using (var ctx = new MyContext())
{
var queryResults = await ctx.EmployeeData.Where(t=>t.EmployeeId == SelectedEmployee.Id).ToArrayAsync();
SelectedEmployeeDatas.Clear();
foreach (var data in queryResults)
{
SelectedEmployeeDatas.Add(data);
}
}
}
以上是关于UI响应性并使用WPF中的“SelectedItem”ListView / ListBox的主要内容,如果未能解决你的问题,请参考以下文章
C# WPF 如何在向 Stackpanel 添加许多 UI 元素时保持应用程序响应