在行为之前触发树视图项目的视觉选择
本文关键字:项目 视图 视觉 选择 | 更新日期: 2023-09-27 18:18:08
我最近开始使用wpf。我有一个简单的树视图与OnSelectedItemChanged事件:
private void Treeview1_OnSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
Thread.Sleep(1000);
}
我得到的当前工作流:
- 用户点击树视图项。
- 代码睡觉。
- 树视图项被直观地选中。
这是一个非常无响应的工作流程。我需要的是:
- 用户点击树视图项。
- 树视图项被直观地选中。
- 代码睡觉。
我能以某种方式触发视觉点击选择吗?
可以。
您所要做的就是不要阻塞UI线程,以便Dispatcher
可以选择TreeViewItem
。
最好的方法可能是在事件处理程序中使用async/await
。如果您不使用MVVM,并且需要直接操作您的UI元素,您可以这样做:
private async void Treeview1_OnSelectedItemChanged(object sender,
RoutedPropertyChangedEventArgs<object> e)
{
// TreeViewItem gets selected immediately.
// Now let's do some background work, for example getting some data.
await Task.Run(() => DoSomeBackgroundWork());
// And fill the DataGrid with the results.
// Thanks to async/await we're already in the dispatcher thread again.
dataGrid.Items.Add(...);
}
private void DoSomeBackgroundWork()
{
// Simulate some blocking synchronous work.
Thread.Sleep(1000);
}
如果您使用带有数据绑定的MVVM(我强烈推荐),那么您可能不需要在调度程序线程中填充ViewModel
的内容。
相反,您可以在async
上下文中执行此操作,然后从上面告诉await
,之后不需要切换到调度程序线程的上下文:
await Task.Run(() => DoSomeBackgroundWork())
.ConfigureAwait(continueOnCapturedContext: false);
myViewModel.Items.Add(...);
但是请注意,您很可能还需要应用某种形式的并发安全性,因为如果用户快速单击多个TreeViewItems
,则无法保证多个Task.Run()
不会相互干扰。
例如,你可以看看斯蒂芬·克利里。关于这个主题,他写了一些非常棒的文章。
或者Stephen Toub,他与。net中异步编程的实现密切相关。
作为一般建议,您应该尝试在分派器线程中尽可能少地执行操作。只做绝对需要的操作,比如直接修改UI元素。