2011-03-10 53 views
0

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(),但似乎冻结了用户界面。

+0

解决了这个问题。真的很明显。我现在使用包装器方法来扩展foreach循环中的祖先,它返回IsExpanded属性使用的任务。然后可以在该任务上调用Wait()方法,以确保在继续之前完全加载下一个祖先的父项。 – pilsdumps 2011-03-11 09:09:20

回答

0

自己解决了这个问题。真的很明显。我现在使用包装器方法来扩展foreach循环中的祖先,它返回IsExpanded属性使用的任务。然后可以在该任务上调用Wait()方法,以确保在继续之前完全加载下一个祖先的父项。

+2

有趣!你能分享一些源代码吗? – 2012-03-19 18:53:11