2012-02-14 78 views
0

我有一個樹視圖在我通過WCF方法動態構建的SL 4應用程序中。樹視圖由文件夾和文檔組成。當需要添加批量文檔時,我需要能夠重建樹。清除層次結構的silverlight樹視圖

如何清除SL樹視圖中的所有項目?並且不要說TreeView.Items.Clear(),因爲這不起作用。也不可能使用foreach循環來移除所有項目及其子項。我說文章here,但在任何地方都看不到TreeView.Children.CopyTreeView.Items.Copy。這是我試過的最後一件事,而且我不知所措...

請讓我知道如果你知道一種方法來完成這件事......謝謝!

Private Sub NewDocumentTree_Received(ByVal sender As Object, ByVal e As GetDocumentTreeCompletedEventArgs) 
     Me.ThisDocTreeView = e.Result 
     ClearTree() 
     PopulateDocTreeView() 
    End Sub 

    Private Sub ClearTree() 
     Dim tempTree As New TreeView() 
     tempTree = CopyTreeViewToNewObject(Me.docTreeView) 
     For Each tvi As TreeViewItem In tempTree.Items 
      For Each sub_tvi As TreeViewItem In tvi.Items 
       For Each d_tvi As TreeViewItem In sub_tvi.Items 
        RemoveTreeViewSubItems(d_tvi) 
       Next 
       RemoveTreeViewSubItems(sub_tvi) 
      Next 
      RemoveTreeViewSubItems(tvi) 
     Next 
     tempTree.UpdateLayout() 

     Me.docTreeView = tempTree 
     Me.docTreeView.UpdateLayout() 
    End Sub 

    Private Sub RemoveTreeViewSubItems(ByVal tvi As TreeViewItem) 
     For Each sub_tvi As TreeViewItem In tvi.Items 
      tvi.Items.Remove(sub_tvi) 
      tvi.UpdateLayout() 
     Next 
    End Sub 

    Private Function CopyTreeViewToNewObject(ByVal treeview As TreeView) As TreeView 
     Dim newTree As New TreeView() 
     For Each Parent As TreeViewItem In treeview.Items 
      newTree.Items.Add(GetTreeViewItemAndChildren(Parent)) 
     Next 
     Return newTree 
    End Function 

    Private Function GetTreeViewItemAndChildren(ByVal treeViewItem As TreeViewItem) 
     Dim ParentalItem As New TreeViewItem 
     ParentalItem = treeViewItem 
     For Each child As TreeViewItem In treeViewItem.Items 
      Dim firstChild As New TreeViewItem 
      firstChild = child 
      For Each subChild As TreeViewItem In child.Items 
       Dim secondChild As New TreeViewItem 
       secondChild = child 
       firstChild.Items.Add(secondChild) 
      Next 
      ParentalItem.Items.Add(firstChild) 
     Next 

     Return ParentalItem 
    End Function 

UPDATE:下面是從一個批量更新到樹的我的WCF服務,並且構建樹視圖中的主方法接收通知的方法。

Private Sub NewDocumentTree_Received(ByVal sender As Object, ByVal e As GetDocumentTreeCompletedEventArgs) 

     Me.ThisDocTreeView = e.Result 

     Me.docTreeView.Items.Clear() 

     Me.docTreeView.UpdateLayout() 

     PopulateDocTreeView() 

    End Sub 

Private Sub PopulateDocTreeView() 

     'ensure all items are clear 
     Me.docTreeView.Items.Clear() 

     'loop through root folder to extract parent "user" folders, and examine sub folders 
     For Each folder As PortalOnline.PortalDocRootFolder In ThisDocTreeView.RootFolders 

      'get this users folder as a tree view items 
      Dim parent As TreeViewItem = GetParentTreeViewFolder(folder) 

      'define a new list of category folders based on this users documents 
      Dim catFolders As List(Of TreeViewItem) = GetCategoryFolderList(folder) 

      'loop through the subfolders of the users parent folder for document and get each document folder 
      'as a new tree view item 
      For Each child As PortalOnline.PortalDocInfo In folder.SubFolders 

       'define the document tree view item 
       Dim childItem As TreeViewItem = GetDocumentTreeItem(child, folder) 

       'loop through the category folders, and add the document tree view item to the appropriate folder 
       For Each categoryfolder As TreeViewItem In catFolders 

        Dim childMeta As DocTreeViewItem = childItem.Tag 

        'if the category tree veiw item head matches the document category of the document tree view item 
        'then add the document tree view item into that category folder 
        If categoryfolder.Header = childMeta.DocumentCategory Then 

         categoryfolder.Items.Add(childItem) 

        End If 

       Next 

      Next 

      'add all category folders to the users parent folder 
      For Each subfolder As TreeViewItem In catFolders 

       parent.Items.Add(subfolder) 

      Next 

      'add the users parent folder to the tree view 
      docTreeView.Items.Add(parent) 

     Next 

    End Sub 

在頁面加載時,和NewDocumentTree_Received方法時,WCF發佈和更新被稱爲樹形視圖顯然是被填充。

在實例中的錯誤: 「具有相同鍵的項目已alread增加了」

它告訴我的樹沒有被清除和更新,否則樹就不會在第一填充放置...希望幫助澄清情況。

+0

注意* PopulateTreeView()方法以Me.docTreeView.Items.Clear()開始。 – wakurth 2012-02-14 20:24:21

+0

您能解釋爲什麼'treeView.Items.Clear()'不起作用嗎?它會給出錯誤,不清楚所有項目,或者是什麼?我進行了一次快速測試,似乎對我有用。 – 2012-02-14 22:17:53

+0

當然..當我調用treeView.Items.Clear()絕對沒有任何反應。我也嘗試過treeView.Items.UpdateLayout()之後...仍然沒有。這很簡單。 – wakurth 2012-02-14 22:38:14

回答

0

我改變了我構建TreeView的方式,所以我使用TreeView.ItemsSource併爲其指定了一個TreeViewItems列表。然後,我使用TreeView.ClearValue(TreeView.ItemsSourceProperty)方法清除樹,然後用新的項目源重新填充它..這似乎完成了工作。

Me.docTreeView.ClearValue(TreeView.ItemsSourceProperty) 

Me.docTreeView = New TreeView 

Me.docTreeView.ItemsSource = Nothing 

PopulateDocTreeView() 
0

我無法複製TreeView.Items.Clear()的任何問題。下面是我加入到Visual Web Developer中創建新的Silverlight應用程序項目的代碼快遞:

MainPage.xaml中(根<UserControl>元素的內容):

<StackPanel> 
    <Button Content="1" Click="Button1_Click" /> 
    <Button Content="2" Click="Button2_Click" /> 
    <sdk:TreeView x:Name="docTreeView" /> 
</StackPanel> 

MainPage.xaml.cs中(以下MainPage()構造函數) :你有沒有共享

private void Button1_Click(object sender, System.Windows.RoutedEventArgs e) 
    { 
     List<TreeViewItem> items3 = new List<TreeViewItem>() { new TreeViewItem() { Header = "1.b.i" }, new TreeViewItem() { Header = "1.b.ii" }, new TreeViewItem() { Header = "1.b.iii" } }; 
     List<TreeViewItem> items2 = new List<TreeViewItem>() { new TreeViewItem() { Header = "1.a" }, new TreeViewItem() { Header = "1.b" }, new TreeViewItem() { Header = "1.c" } }; 
     items3.ForEach(item => items2[1].Items.Add(item)); 
     List<TreeViewItem> items1 = new List<TreeViewItem>() { new TreeViewItem() { Header = "1" }, new TreeViewItem() { Header = "2" }, new TreeViewItem() { Header = "3" } }; 
     items2.ForEach(item => items1[0].Items.Add(item)); 

     docTreeView.Items.Clear(); 
     items1.ForEach(item => docTreeView.Items.Add(item)); 
    } 

    private void Button2_Click(object sender, System.Windows.RoutedEventArgs e) 
    { 
     List<TreeViewItem> items3 = new List<TreeViewItem>() { new TreeViewItem() { Header = "TWO.B.I" }, new TreeViewItem() { Header = "TWO.B.II" }, new TreeViewItem() { Header = "TWO.B.III" } }; 
     List<TreeViewItem> items2 = new List<TreeViewItem>() { new TreeViewItem() { Header = "TWO.A" }, new TreeViewItem() { Header = "TWO.B" }, new TreeViewItem() { Header = "TWO.C" } }; 
     items3.ForEach(item => items2[1].Items.Add(item)); 
     List<TreeViewItem> items1 = new List<TreeViewItem>() { new TreeViewItem() { Header = "ONE" }, new TreeViewItem() { Header = "TWO" }, new TreeViewItem() { Header = "THREE" } }; 
     items2.ForEach(item => items1[1].Items.Add(item)); 

     docTreeView.Items.Clear(); 
     items1.ForEach(item => docTreeView.Items.Add(item)); 
    } 

的一件事是你用它來顯示您的TreeView的XAML。你沒有任何機會,將你的XAML中樹視圖的ItemsSource綁定到某個東西上,對嗎? (我這樣說是因爲你提到在ItemsSourceProperty上調用ClearValue似乎爲你解決了一些問題,這就暗示了該屬性存在綁定。但是,我的理解是,其餘的代碼以代碼形式組裝樹,落後分配給Items屬性)


順便說一下,下面的循環(在RemoveTreeViewSubItems)將無法正常工作,除非tvi.Items已經是空的。

For Each sub_tvi As TreeViewItem In tvi.Items 
     tvi.Items.Remove(sub_tvi) 
     tvi.UpdateLayout() 
    Next 

你不能從一個集合作爲刪除項目你正在迭代它。如果您嘗試這樣做,您將得到'由於對象的當前狀態而導致操作無效'錯誤。

0

我有一個類似的問題,Items.Clear()會掛起我的應用程序。我用下面的代碼修復了它。它從小孩身上移除每個項目,然後繼續前進。

private void ClearFix() 
    { 
      RemoveKids(this.Items); 
    } 

    private void RemoveKids(ItemCollection ItemsColl) 
    { 
     foreach (object obj in ItemsColl.ToArray()) 
     { 
      TreeViewItem tvi = obj as TreeViewItem; 

      if (tvi == null) 
       continue; 

      if (tvi.HasItems) 
       RemoveKids(tvi.Items); 

      this.Items.Remove(tvi); 
     } 
    } 

通知我只好用ItemColl.ToArray(),因爲如果你改變你遍歷集合,你會得到一個錯誤。

不知道這是否添加到問題,但我實際上並沒有使用TreeViewItem,而是從它繼承的對象。