代码之家  ›  专栏  ›  技术社区  ›  Stavros

在WPF Treeview中搜索特定的Treeview项目

  •  2
  • Stavros  · 技术社区  · 6 年前

    我正在与wpf合作 TreeView 。我正在尝试搜索中的所有项目 树状视图 找到所需的 TreeViewItem 在它里面。

    我的代码:

    parent 是一个 string 我正在搜索的所需项目的标题。

    foreach (TreeViewItem item in treeView.Items)
    {    
       if (item.Header.ToString().Contains(parent))
       {
           //Do Something to item that is found 
       }
    }
    

    我对这段代码的问题是,它将搜索 树状视图 .如果有 item 项目 树状视图 ,然后 项目 找不到。尽管如此,我还是将其添加到了代码中,但这只会将问题延长到 树状视图

    foreach (TreeViewItem item in treeView.Items)
    {
       foreach(TreeViewItem subItem in item.Items)
       {
           if (subItem.Header.ToString().Contains(parent))
           {
               //Do Something to item that is found         
           }
       }    
       if (item.Header.ToString().Contains(parent))
       {
           //Do Something to item that is found 
       }
    }
    

    有没有办法搜索整个 树状视图 以及所有 items 在它里面?我可以搜索一下 树状视图 递归地?

    4 回复  |  直到 6 年前
        1
  •  4
  •   Andy    6 年前

    您应该研究递归。 本质上,您需要一个接受treeviewitem并遍历其所有子项的方法。 对于其中的每一个,方法都会调用自身,并传入子级。 如果你以前从未做过这件事,当你第一次看到它的时候,你会觉得有点心碎。了解原则。 但大致上:

        private void recurseItem(TreeViewItem item)
        {
            foreach (var subItem in item.Items)
            {
                // compare header and return that item if you find it
                if(!gotTheItem)
                   recurseItem(subItem);
            }
        }
    

    您需要一个foreach循环,通过树的顶级项将每个项传递给它。 不要只是将其粘贴(然后学习剪切和粘贴)阅读递归并思考它。 请注意,您希望在获得该项后通过设置bool标志来发出找到该项的信号,并避免重复所有其余内容。

    注意,这段代码主要是为了向新手介绍递归的思想。它不是理想的剪切粘贴解决方案。
    如果您尝试使用绑定的treeview进行此操作,则会发现Items集合包含您绑定的对象,而不是treeview项。

        2
  •  2
  •   Tronald    6 年前

    Andy的解决方案可以满足您的需要,但更通用和可重用的解决方案是使用 ItemCollection 。使用此选项,可以传递继承 ItemCollection项目集合 同时避免子项出现异常。如果树中有不同类型的子项,这将是一个很好的选择。

    private void IterateTree(ItemCollection items)
    {     
        //Iterate each item
        foreach (var item in items)
        {
            //Your IF logic here
    
            //Iterate again if item contains sub items.
            if (item is ItemsControl)
            {
                ItemsControl ic = (ItemsControl)item;
                IterateTree(ic.Items); //Recursive call
            }
        }      
     }
    
        3
  •  1
  •   Stavros    6 年前

    我创建了两个递归方法。第一个最初搜索 TreeView 对于所需的项目,第二个搜索 item 直到找到所需的项目。然后,该方法返回所需的项,我可以按照自己的意愿对其进行操作。

    代码:

    /// <summary>
        /// Recursivly search the treeview until desired TreeViewItem is found
        /// </summary>
        /// <param name="_treeView"></param>
        /// <param name="_parent"></param>
        /// <returns></returns>
        private TreeViewItem SearchTreeView(TreeView _treeView, string _parent)
        {
            TreeViewItem foundItem = null;
            foreach (TreeViewItem item in _treeView.Items)
            {
                if (item.Header.ToString().Contains(_parent))
                {
                    foundItem = item;
                }
                else
                {
                    foundItem = SearchTreeView(item, _parent);
                }
            }
            return foundItem;
        }
        /// <summary>
        /// Recursivly search the treeviewitem until desired TreeViewItem is found
        /// </summary>
        /// <param name="_item"></param>
        /// <param name="_parent"></param>
        /// <returns></returns>
        private TreeViewItem SearchTreeView(TreeViewItem _item, string _parent)
        {
            TreeViewItem foundItem = null;
            foreach (TreeViewItem subItem in _item.Items)
            {
                if (subItem.Header.ToString().Contains(_parent))
                {
                    foundItem = subItem;
                }
                else
                {
                    foundItem = SearchTreeView(subItem, _parent);
                }
            }
            return foundItem;
        }
    
        4
  •  0
  •   ahmad khosravani    4 年前

    使用 ItemsControl 您可以在两者中搜索 TreeView TreeViewItem 子项。这是我的代码:

        private TreeViewItem SearchTreeView(ItemsControl item, string header)
        {
            TreeViewItem foundItem = null;
            foreach (TreeViewItem subItem in item.Items)
                foundItem = subItem.Header.ToString().Contains(header) ? subItem : SearchTreeView(subItem, header);
            return foundItem;
        }