2011-03-10 52 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