C# HierarchycalDataTemplate TreeView-ContainerFromItem仅为第一个项返回TreeView项
我有一个树状视图,如下所示:C# HierarchycalDataTemplate TreeView-ContainerFromItem仅为第一个项返回TreeView项,c#,wpf,treeview,C#,Wpf,Treeview,我有一个树状视图,如下所示: <TreeView Loaded="tv_Loaded_1" DockPanel.Dock="Bottom" Name="tv" ItemsSource="{Binding XPath=*}"> <TreeView.ItemTemplate> <HierarchicalDataTemplate ItemsSource="{Binding XPath=*}"&
<TreeView
Loaded="tv_Loaded_1"
DockPanel.Dock="Bottom"
Name="tv"
ItemsSource="{Binding XPath=*}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate
ItemsSource="{Binding XPath=*}">
<StackPanel
Orientation="Horizontal">
<TextBlock
Text="{Binding Name}"></TextBlock>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
在代码隐藏中,我使用以下xml作为数据上下文:
XmlDocument doc = new XmlDocument();
doc.LoadXml(@"<a><b><c></c><d></d></b><e><f></f><g></g></e></a>");
DataContext = doc;
XmlDocument doc=新的XmlDocument();
doc.LoadXml(@“);
DataContext=doc;
TreeView生成的结果很好,但在枚举项时,我只为第一个XmlNode(根节点,即
)获取TreeView项,层次结构中的其余XmlNodes没有任何对应的TreeView项
private IEnumerable<TreeViewItem> Enumerate(ItemCollection items)
{
foreach (XmlElement element in items)
{
TreeViewItem item = tv.ItemContainerGenerator.ContainerFromItem(element) as TreeViewItem;
if (item != null) //When second call with <a>.Items, item is null
{
yield return item;
}
//Enumerate is called again with <a>.Items
//Exception in second call, because item is null
foreach (TreeViewItem i in Enumerate(item.Items))
{
yield return i;
}
}
}
private void tv_Loaded_1(object sender, RoutedEventArgs e)
{
var list = Enumerate(tv.Items).ToList();
}
private IEnumerable枚举(ItemCollection项)
{
foreach(项目中的XmlElement)
{
TreeView项目=tv.ItemContainerGenerator.ContainerFromItem(元素)作为TreeView项目;
if(item!=null)//第二次调用.Items时,item为null
{
收益回报项目;
}
//使用.Items再次调用枚举
//第二次调用中出现异常,因为项为null
foreach(枚举中的TreeViewItem i(item.Items))
{
收益率i;
}
}
}
已加载私有无效电视(对象发送器,路由目标)
{
var list=Enumerate(tv.Items).ToList();
}
为什么树中的其余XmlNodes没有任何TreeViewItem
非常感谢您的帮助。因为其他项目不在电视中,它们在“a”树项目中。但是,它们也不是“a”,因为TreeViewItem没有扩展,布局也没有更新 您可以通过传入ItemsControl(tv或父树eviewitem)并使用它获取ContainerFromItem来使其工作。但是,在获得容器之前,您必须展开项目并更新其布局 下面是一些执行上述操作的代码。一个副作用是树被完全扩展
private IEnumerable<TreeViewItem> Enumerate(ItemsControl itemsControl, ItemCollection items)
{
foreach (XmlElement element in items)
{
TreeViewItem item = itemsControl.ItemContainerGenerator.ContainerFromItem(element) as TreeViewItem;
if (item != null) //When second call with <a>.Items, item is null
{
item.IsExpanded = true;
item.UpdateLayout();
yield return item;
}
//Enumerate is called again with <a>.Items
//Exception in second call, because item is null
foreach (TreeViewItem i in Enumerate(item, item.Items))
{
yield return i;
}
}
}
private void tv_Loaded_1(object sender, RoutedEventArgs e)
{
var list = Enumerate(tv, tv.Items).ToList();
}
private IEnumerable枚举(ItemsControl ItemsControl,ItemCollection items)
{
foreach(项目中的XmlElement)
{
TreeViewItem item=itemsControl.ItemContainerGenerator.ContainerFromItem(元素)作为TreeViewItem;
if(item!=null)//第二次调用.Items时,item为null
{
item.IsExpanded=true;
item.UpdateLayout();
收益回报项目;
}
//使用.Items再次调用枚举
//第二次调用中出现异常,因为项为null
foreach(枚举中的TreeViewItem i(项,项.项))
{
收益率i;
}
}
}
已加载私有无效电视(对象发送器,路由目标)
{
var list=枚举(tv,tv.Items).ToList();
}
实际上,您只需要传入ItemsControl。此外,我还添加了一些代码来关闭树
private IEnumerable<TreeViewItem> Enumerate(ItemsControl itemsControl)
{
foreach (XmlElement element in itemsControl.Items)
{
TreeViewItem item = itemsControl.ItemContainerGenerator.ContainerFromItem(element) as TreeViewItem;
if (item != null) //When second call with <a>.Items, item is null
{
item.IsExpanded = true;
item.UpdateLayout();
yield return item;
}
//Enumerate is called again with <a>.Items
//Exception in second call, because item is null
foreach (TreeViewItem i in Enumerate(item))
{
yield return i;
}
}
}
private void tv_Loaded_1(object sender, RoutedEventArgs e)
{
var list = Enumerate(tv).ToList();
// Unexpand all the items
list.ForEach(tvi => tvi.IsExpanded = false);
}
private IEnumerable枚举(ItemsControl ItemsControl)
{
foreach(itemsControl.Items中的XmlElement元素)
{
TreeViewItem item=itemsControl.ItemContainerGenerator.ContainerFromItem(元素)作为TreeViewItem;
if(item!=null)//第二次调用.Items时,item为null
{
item.IsExpanded=true;
item.UpdateLayout();
收益回报项目;
}
//使用.Items再次调用枚举
//第二次调用中出现异常,因为项为null
foreach(枚举中的TreeViewItem i(项目))
{
收益率i;
}
}
}
已加载私有无效电视(对象发送器,路由目标)
{
var list=Enumerate(tv.ToList();
//取消展开所有项目
list.ForEach(tvi=>tvi.IsExpanded=false);
}
非常感谢。我试试这个。