2010-06-28 64 views
1

我有一個綁定到我無法控制的集合類的TreeView。這個類內部是一個對象集合,每個對象都有自己的項目集合。此層次結構固定爲3深。 TreeView的子元素包含在ObservableCollection中,並相應地在TreeView中進行更新。每個對象中的集合都是不可觀察的,因此每次向其中一個子對象添加對象時,我都必須手動將數據綁定到TreeView。這會導致所有展開的子項都重置爲未展開狀態。我試圖緩存已擴展的對象,以便在重新綁定後可以重新展開。孩子們按我期望的方式工作,但是當我嘗試擴展TreeView的孫子時,我得到一個空對象。如何在重新綁定後緩存TreeViewItems以重新展開?

爲了得到一個TreeViewItem我使用的ItemsControl的ItemContainerGenerator屬性:

TreeViewItem cfItem = treeView.ItemContainerGenerator 
    .ContainerFromItem(obj) as TreeViewItem; 
cfItem.IsExpanded = true; 

第二級藏品都有自己的父對象的引用。所以,因爲我有很多這樣的對象,它們被循環遍歷,並且每個都使用它的父對象來查找它的父對象的TreeViewItem。他們被添加到收集的順序保證(我認爲)孩子總是在父母之後被處理。因此,我得到這個醜陋的代碼行:

qualItem = (
    (TreeViewItem)treeView.ItemContainerGenerator 
     .ContainerFromItem(
      ((Child)obj).ParentObject 
     ) 
    ) 
    .ItemContainerGenerator.ContainerFromItem(obj) as TreeViewItem; 

這條線時,它試圖從項目obj中的容器總是失敗。它成功獲取父TreeViewItem,但試圖獲取Child的TreeViewItem容器時,我總是收到null。該文件指出,ContainerFromItem()返回

「那 對應於給定的項目。一個System.Windows.UIElement返回 空,如果該項目不屬於 項目收集,或者如果 系統。 Windows.UIElement尚未爲其生成 。「

我知道第二級孩子存在父母的項目集合中。我檢查了VS 2010中的調試器,並且所有的項目都在那裏。我花了很長時間在Google上搜索答案,發現有人說容器項目是在後臺工作線程上創建的,並且在嘗試獲取子項目容器時可能不會生成。我試着等待ItemContainerGenerator的Status屬性等於GeneratorStatus.ContainersGenerated,但我仍然得到相同的結果。我需要以某種方式爲我的二級孩子獲取TreeViewItem容器,以便它們可以像第一級孩子一樣重新展開。

回答

0

解決方法是在數據和TreeView之間添加另一個抽象層。頂級集合是一個ObservableCollection,它包含幾個實現INotifyPropertyChanged的ViewModel,並且它們下面的樹中還有ObservableCollections元素。該系統允許WPF更輕鬆地綁定並跟蹤正在添加和刪除的元素。

我的主要信息來源是這篇文章:

http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

0

「是對應於給定項目A System.Windows.UIElement。如果該項目不屬於該項目集合,或如果System.Windows.UIElement尚未爲它產生返回null。 「

看起來像是因爲VirtualizationUIElement找不到,當你正在尋找它。如果集合不太大,請嘗試關閉Virtualization

+0

的VirtualizingStackPanel.IsVirtualizing屬性設置爲false,什麼也沒做。 TreeView元素上是否有另一個IsVirtualizing屬性? – 2010-06-28 19:20:20