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