12,349,785 members (26,794 online)
Tip/Trick
alternative version

5.2K views
4 bookmarked
Posted

# Quick and Dirty TreeView

, 25 Mar 2013 CPOL
 Rate this:
Design to create a simple tree view that can be copy and pasted

## Introduction

There are times when it would be convenient to have an easy way to display hierarchical data as tree. This can be done using tree view, but sometimes just a text version is acceptable, with the advantages of being easy to handle the data, not having to carry a lot of objects and values around, and for copy and pasting. It is not a hard problem to solve; it just needs to be thought about a little while.

## Implementation

The approach used is a recursion, with a `List<string>` being used to capture a tree. When assembling the tree, each subtree is created as a `List<string>` and combined into a `List<List<string>>`. The first element in the `List<string>` is the node that needs be attached to the base node of the tree. When assembling the nodes of a node in the tree, the first `List<string>` in the `List<List<string>> `is the parent, and the children are represented by the following nodes. The following code will put a horizontal line made up of the “|” character from the parent for each node, ending at the start of the last node. Where the base node starts for each child node, a “+” character with a vertical line right (“-“) will be inserted:

```private static List<string> AppendTree(List<list<string>> limbs)
{
var list = new List<string>();

if (limbs.Any())
{
for (int i = 1; i < limbs.First().Count; i++)
}

for (int i = 1; i < limbs.Count - 1; i++)
{
if (limbs[i].Count > 0)
{
for (int j = 1; j < limbs[i].Count; j++)
}
}

if (limbs.Last().Count > 1)
{
for (int j = 1; j < limbs.Last().Count; j++)
}

return list;
}```

What is finally returned is a `List<string>`.

I also have several helper methods, one will take a list of arguments and put them into a comma delimited string enclosed in brackets, and add a spacer line:

```private static List<string> Enclose(params object[] o)
{
var s = o.Select(i => i.ToString());
var str = string.Join(", ", s);
return new List<string> { string.Format("< {0} >", str), string.Empty };
}```

A second method will take a `string `and an `IEnumerable<T>` and convert it so something similar, except this allows quick conversion of list data to a single line:

```private static List<string> EncloseList<t>(string s, IEnumerable<t> o)
{
return Enclose(s, string.Join(", ", o.Select(i => i.ToString())));
}```

A fourth method is just a simple factory for creating a List<`List<string>`> from a single `List<string>` which becomes the first element of the new list. It just cleans up creating the conversion methods:

```private static List<list<string>> StartList(List<string> list)
{
return new List<list<string>> { list };
}```

One final helper method is used after the objects to displayed in the tree are process. It converts the `List<string>` to a single `string `with carriage returns between the `string`s in the `List<string>`:

```public static string Convert(IEnumerable<string> values)
{
var sb = new StringBuilder();
foreach (var value in values)
{
sb.AppendLine("    " + value);
}
return sb.ToString();
}```

To make life simple, the method `Convert `is overloaded. Each `Convert `method takes a single argument and returns a `List<string>`. The simplest `convert `would just return the result of a call to the `Enclose `method:

```public static List<string> Convert(Class4 values)
{
return Enclose("Class 4", values.Id, values.Name, values.Property1);
}```

To create a class to display a class and its children as a limb:

```public static List<string> Convert(Class1 values)
{
var result = StartList(Enclose("Class 1", values.Id, values.Name,
values.Property1));
if (values.Children != null)
return AppendTree(result);
}```

Once all the methods are set up to display a tree for an object and its children, two method calls are required, and it is the same for all classes for which `Convert `methods have been created:

```var str = ConvertToTreeViewString.Convert(
ConvertToTreeViewString.Convert(data)); ```

The result would look something like this:

```< Class 1, 1, name1, property1a >
|
+- < Class 2, 1, name2a, property2a >
|      |
|      +- < Property4, a, b, c, d >
|      |
|      +- < Class 2, 2, name3a, property3a >
|      |      |
|      |      +- < Property4, 1, 2, 3, 4 >
|      |
|      +- < Class 2, 3, name3b, property3d >
|              |
|              +- < Property4, 5, 6, 7, 8 >
|              |
|              +- < Class 4, 4, name4a, property4a >
|              |
|              +- < Class 4, 5, name4b, property4d >
|
+- < Class 2, 6, name2b, property2d >
|
+- < Property4, a, b, c, d >
|
+- < Class 2, 6, name3c, property3g >
|       |
|      +- < Property4, 7, 2, 3, 4 >
|
+- < Class 2, 1, name3d, property3j >
|
+- < Property4, 8, 2, 3, 4 >
```

If you have control of your objects, you can simplify things by having the object information to be displayed in the tree returned in the `ToString()` method. I did not have that luxury since the objects in the tree were generated objects. Also I did not have a standard name for the children of an object for the same reason. I made a little bit of use of generics in my code when children were displayed as list, but that was it. A different application may allow use of generics to reduce the number of convert methods required.

## Share

 Software Developer (Senior) Clifford Nelson Consulting United States
Has been working as a C# developer on contract for the last several years, including 3 years at Microsoft. Previously worked with Visual Basic and Microsoft Access VBA, and have developed code for Word, Excel and Outlook. Started working with WPF in 2007 when part of the Microsoft WPF team. For the last eight years has been working primarily as a senior WPF/C# and Silverlight/C# developer. Currently working as WPF developer with Clarity Medical in Pleasanton, CA redesigning their UI for their camera system. he can be reached at qck1@hotmail.com.

## You may also be interested in...

 First Prev Next
 My vote of 1 supernorb26-Mar-13 2:57 supernorb 26-Mar-13 2:57
 Re: My vote of 1 Clifford Nelson26-Mar-13 5:53 Clifford Nelson 26-Mar-13 5:53
 Last Visit: 31-Dec-99 18:00     Last Update: 25-Jun-16 11:44 Refresh 1