我有一个树视图在我通过WCF方法动态构建的SL 4应用程序中。树视图由文件夹和文档组成。我需要能够在添加批量文档时重建树。
如何清除SL树视图中的所有项目?并且不要说TreeView.Items.Clear()
因为这不起作用。也不可能使用foreach
循环删除所有项目及其子项。我说了一篇文章here,但在任何地方都看不到TreeView.Children.Copy
或TreeView.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
更新:以下是从我的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
当页面加载时,树视图显然正在填充,并且在WCF发布和更新时调用NewDocumentTree_Received方法。
实例中的错误: "已添加具有相同键的项目"
这告诉我树没有被清除和更新,否则树不会首先填充...希望帮助澄清情况。
答案 0 :(得分:0)
我改变了构建TreeView的方式,因此我使用TreeView.ItemsSource并为其分配TreeViewItems列表。然后我使用TreeView.ClearValue(TreeView.ItemsSourceProperty)方法清除树,然后使用新项源重新填充它..这似乎可以完成工作。
Me.docTreeView.ClearValue(TreeView.ItemsSourceProperty)
Me.docTreeView = New TreeView
Me.docTreeView.ItemsSource = Nothing
PopulateDocTreeView()
答案 1 :(得分:0)
我无法使用TreeView.Items.Clear()
重现任何问题。下面是我在Visual Web Developer Express中添加到新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
树视图绑定到某个东西,对吗? (我这样说是因为你提到在ClearValue
上调用ItemsSourceProperty
似乎可以为你解决问题,这表明我对该属性有约束力。但是,我的理解是其余的您的代码通过分配给Items
属性来组装代码隐藏中的树。)
顺便提一下,以下循环(在RemoveTreeViewSubItems
中)不起作用,除非tvi.Items
已经为空:
For Each sub_tvi As TreeViewItem In tvi.Items
tvi.Items.Remove(sub_tvi)
tvi.UpdateLayout()
Next
在迭代集合时,无法从集合中删除项目。如果您尝试这样做,您将得到“由于对象的当前状态而导致操作无效”错误。
答案 2 :(得分: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,而是继承了它的对象。