WPF MVVM树形异步加载我使用MVVM利用由约什 - 史密斯为证明TreeViewItemViewModels简化与一个TreeView工作http://www.codeproject.com/KB/WPF/TreeViewWithViewModel.aspx与任务
我树状表示关系数据库中的记录一个WPF应用程序,每个节点都有按需加载的儿童。为了提高UI的响应速度,我一直试图使用.NET 4.0中的任务异步加载数据,但我努力实现这一点令人满意。
的treeviewitemviewmodel IsExpanded属性看起来是这样的:
public bool IsExpanded
{
get { return _isExpanded; }
set
{
if (_isExpanded == value)
return;
if (!_isSelected)
IsSelected = true;
_isExpanded = value;
if (_isExpanded &&
_parent != null &&
_parent.GetType() != typeof(FirstGenerationViewModel))
_parent.IsExpanded = true;
ApplicationSetup.Messenger.NotifyColleagues(ApplicationSetup.MSG_WORKING, true);
Task task = Task.Factory.StartNew(() =>
{
LoadChildren();
})
.ContinueWith((t) =>
{
this.OnPropertyChanged("IsExpanded");
ApplicationSetup.Messenger.NotifyColleagues(ApplicationSetup.MSG_WORKING, false);
}, ApplicationSetup.UIScheduler);
}
}
如果我手动选择项目,并展开和折叠他们都按预期工作 - 工作动画显示,同时LoadChildren()执行,然后将项目扩大当调用OnPropertyChanged并关闭动画时。
但是,我试图实现搜索功能。如果一个记录已经被加载,我只需迭代树视图直到找到它,然后选择它。但是,如果未加载该进程应搜索数据库中的记录然后显示它。由于记录是按需加载,过程中得到追捧的项目,并从数据库中它的祖先,并试图扩大反过来每个祖先然后最终选择寻求项目:
foreach (var item in ancestors.Keys)
{
TreeViewItemViewModel tv = _fgvm.recordsViewHelper.GetTreeViewItem(new ItemArgs
{
TargetTableName = item,
TargetPk = ancandtarget[item]
});
tv.IsExpanded = true;
}
如果寻求产品层次结构中的高,这有效。但是,当记录嵌套了一些项目时,tv为空。我认为这是因为该项目在_fgvm.recordsViewHelper.GetTreeViewItem试图在树视图中找到它之前未加载。
我该如何做到这一点?我尝试过使用Wait(),但似乎冻结了用户界面。
解决了这个问题。真的很明显。我现在使用包装器方法来扩展foreach循环中的祖先,它返回IsExpanded属性使用的任务。然后可以在该任务上调用Wait()方法,以确保在继续之前完全加载下一个祖先的父项。 – pilsdumps 2011-03-11 09:09:20