Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / WinForms

Retrieving TreeView nodes as IEnumerable

5.00/5 (2 votes)
30 Jan 2012CPOL 11.3K  
Here is yet another alternative (originally from http://xacc.wordpress.com/2009/03/05/tree-traversal-extension-methods/[^]):public static class TreeExtensions{ public static IEnumerable TraverseDepthFirst( this T t, Func valueselect, Func<T,...
Here is yet another alternative (originally from http://xacc.wordpress.com/2009/03/05/tree-traversal-extension-methods/[^]):

C#
public static class TreeExtensions
{
  public static IEnumerable<R> TraverseDepthFirst<T, R>(
    this T t,
    Func<T, R> valueselect,
    Func<T, IEnumerable<T>> childselect)
  {
    return t.TraverseDepthFirstWithParent(valueselect, childselect).Select(x => x.Key);
  }

  public static IEnumerable<KeyValuePair<R, T>> TraverseDepthFirstWithParent<T, R>(
    this T t,
    Func<T, R> valueselect,
    Func<T, IEnumerable<T>> childselect)
  {
    return t.TraverseDepthFirstWithParent(default(T), valueselect, childselect);
  }

  static IEnumerable<KeyValuePair<R, T>> TraverseDepthFirstWithParent<T, R>(
    this T t,
    T parent,
    Func<T, R> valueselect,
    Func<T, IEnumerable<T>> childselect)
  {
    yield return new KeyValuePair<R, T>(valueselect(t), parent);

    foreach (var i in childselect(t))
    {
      foreach (var item in i.TraverseDepthFirstWithParent(t, valueselect, childselect))
      {
        yield return item;
      }
    }
  }

  public static IEnumerable<R> TraverseBreadthFirst<T, R>(
    this T t,
    Func<T, R> valueselect,
    Func<T, IEnumerable<T>> childselect)
  {
    return t.TraverseBreadthFirstWithParent(valueselect, childselect).Select(x => x.Key);
  }

  public static IEnumerable<KeyValuePair<R, T>> TraverseBreadthFirstWithParent<T, R>(
    this T t,
    Func<T, R> valueselect,
    Func<T, IEnumerable<T>> childselect)
  {
    yield return new KeyValuePair<R, T>(valueselect(t), default(T));

    List<T> children = new List<T>();

    foreach (var e in childselect(t))
    {
      children.Add(e);
      yield return new KeyValuePair<R, T>(valueselect(e), t);
    }

    while (children.Count > 0)
    {
      foreach (var e in new List<T>(children))
      {
        children.Remove(e);
        foreach (var c in childselect(e))
        {
          children.Add(c);
          yield return new KeyValuePair<R, T>(valueselect(c), e);
        }
      }
    }
  }
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)