search WPF Treeview for specific TreeViewItem

2019-08-12 14:18发布

I am working with a wpf TreeView. I am trying to search through all of the items in the TreeView to find the desired TreeViewItem within it.

my code:

parent is a string of the header of the desired item I am searching for.

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

The problem that I am having with this code is that it will search through the top two layers of the TreeView. If there is a item within a item within the TreeView, then the item is not found. With that being said I added to my code but it only prolonged the issue another level into the TreeView.

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

Is there a way to search through the entire TreeView along with all the items within it? Could I possible search the TreeView recursively?

标签: c# wpf treeview
3条回答
Animai°情兽
2楼-- · 2019-08-12 14:53

Andy's solution will work for your needs, but a more versatile and reusable solution would be to iterate using ItemCollection. With this you can pass any object type that inherits an ItemCollection while avoiding exceptions for sub-items that don't. This a great if you have different types of children in your tree.

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
        }
    }      
 }
查看更多
Viruses.
3楼-- · 2019-08-12 14:54

I made two recursive methods. the first initially searched the TreeView for the desired item, then the second searched each item until the desired item was found. the method then returned the desired item which I was able to manipulate like I wanted to.

Code:

/// <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楼-- · 2019-08-12 15:00

You should look into recursion. Essentially, you want a method that takes a treeviewitem and iterates through all it's children. For each of those the method calls itself, passing in the child. If you've never done this before it's a bit mind melting when you first look at it. Get an understanding of the principle. But roughly:

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

You need a foreach loop through the tree's top level items passing each into it. Don't just paste this in (you just learn cut and paste then) read up on recursion and think about it. Note that you will want to signal you found the item by setting a bool flag once you got it and avoid iterating all the rest.

Note that this code is largely intended to introduce a newbie to the idea of recursion. It is not intended to be an ideal cut and paste solution.
If you try this with a bound treeview then you will find that the Items collection has the objects you bound rather than treeviewitems.

查看更多
登录 后发表回答