2012-02-14 113 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,而是从它继承的对象。