简体   繁体   English

HierarchicalDataTemplate TreeView-ContainerFromItem仅返回第一个Item的TreeViewItem

[英]HierarchicalDataTemplate TreeView - ContainerFromItem returns TreeViewItem only for the first Item

I have a TreeView as follows: 我有一个TreeView如下:

<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>

In code behind, I am using the following xml as DataContext: 在后面的代码中,我使用以下xml作为DataContext:

XmlDocument doc = new XmlDocument();
doc.LoadXml(@"<a><b><c></c><d></d></b><e><f></f><g></g></e></a>");
DataContext = doc;

TreeView is generating fine, but while enumerating the Items, I get TreeViewItem only for the first XmlNode(root node ie <a> ) and the remaining XmlNodes down in the hierarchy do not have any corresponding TreeViewItems present. TreeView生成的很好,但是在枚举Items时,我仅对第一个XmlNode(根节点即<a> )获得TreeViewItem,而层次结构中其余的XmlNodes没有任何对应的TreeViewItems。

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();
}

Why the rest of the XmlNodes in the Tree do not have any TreeViewItem present? 为什么树中的其余XmlNodes没有任何TreeViewItem?

Any help is greatly appreciated. 任何帮助是极大的赞赏。

It's because the other items aren't in tv, they are in the 'a' TreeViewItem. 这是因为其他项目不在电视中,它们在“ a” TreeViewItem中。 But, they really are not in 'a' yet either because the TreeViewItem isn't expanded and the layout hasn't been updated. 但是,它们实际上还不在'a'中,这是因为TreeViewItem未展开且布局尚未更新。

You can make it work by passing in the ItemsControl (either tv or the parent TreeViewItem) and using it to get the ContainerFromItem. 您可以通过传入ItemsControl(电视或父级TreeViewItem)并使用它来获取ContainerFromItem来使其工作。 But, you will have to expand the item and update it's layout before you will get a container. 但是,您将必须扩展项目并更新其布局,然后才能获得容器。

Here is some code to do the above. 这是执行上述操作的一些代码。 A side effect will be that the tree is fully expanded. 副作用是树已完全展开。

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();
}

Actually, you only really need to pass in the ItemsControl. 实际上,您实际上只需要传递ItemsControl。 Also, I put some code in to close the tree back up. 另外,我输入了一些代码以关闭树备份。

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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 TreeView的ContainerFromItem返回null - ContainerFromItem at TreeView returns null WPF TreeView HierarchicalDataTemplate获取TreeViewItem - WPF TreeView HierarchicalDataTemplate get TreeViewItem Treeview ContainerFromItem 总是返回 null - Treeview ContainerFromItem always returns null 使用DragDrop和HierarchicalDataTemplate以及其他控件元素作为TreeViewItem的TreeView - TreeView with DragDrop and HierarchicalDataTemplate and other Control Elements as TreeViewItem WPF TreeViewItem上下文菜单使用HierarchicalDataTemplate取消突出显示项目 - WPF TreeViewItem Context Menu Unhighlights Item With HierarchicalDataTemplate HierarchicalDataTemplate TreeviewItem - HierarchicalDataTemplate TreeviewItem HierarchicalDataTemplate中的WPF TreeView过滤器项 - WPF TreeView filter item in HierarchicalDataTemplate 带有HierarchicalDataTemplate的TreeView,是否可以访问诸如MouseDoubleClick和ItemSelected之类的TreeViewItem事件? - TreeView with HierarchicalDataTemplate, Is there a way to access the TreeViewItem events like MouseDoubleClick and ItemSelected? 为TreeView中的选定项目获取TreeViewItem - Getting TreeViewItem for the selected item in a TreeView TreeView.ItemContainerGenerator.ContainerFromItem为非根项目返回null。 解决方法? - TreeView.ItemContainerGenerator.ContainerFromItem returns null for nonroot items. Workaround?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM