I have some serious problems with populating a treeview recursively and I'll apreciate any help.
I have this DataTable:
ItemID ItemDesc Project Room Closet Item1 Item1Desc Project1 RoomE Closet-7 Item2 Item2Desc Project1 RoomW Closet8 Item3 Item3Desc Project1 RoomW Closet8 Item4 Item4Desc Project1 RoomN Closet2 Item5 Item5Desc Project1 RoomN Closet9 Item6 Item6Desc Project2 RoomN Closet2 Item7 Item7Desc Project2 RoomW Closet9
I want to create a TreeView like this:
- Project1
- RoomE
- Closet7
- Item1Desc
- Closet7
- RoomW
- Closet8
- Item2Desc
- Item3Desc
- Closet8
- RoomN
- Closet2
- Item4Desc
- Closet9
- Item5Desc
- Closet2
- RoomE
- Project2
- RoomN
- Closet2
- Item6Desc
- Closet2
- RoomW
- Closet2
- Item7Desc
- Closet2
- RoomN
The way I'm trying to databind the treeview is using
private List<treeDataItem> treeData = new List<treeDataItem>();
mytreeView.DataFieldID = "ID";
mytreeView.DataFieldParentID = "ParentID";
mytreeView.DataTextField = "Text";
mytreeV开发者_Go百科iew.DataValueField = "Value";
mytreeView.DataSource = treeData;
mytreeView.DataBind();
I'm trying to loop thru the DataTable so I can populate treeData but i can't enter the ParentIDs correctly.
Also, to make things complicated the number of fields in the DataTable are variable.
Which means that I can have more fields that identify an item like a "Closet Drawer" and then maybe a "Closet Drawer Section", etc.So the DataTable can one time be like:
ItemID ItemDescription Project Room Closet Closet Drawer
And another time like:
ItemID ItemDescription Project Room Closet Closet Drawer Closet Drawer Section
based on user selection.
Here's the treeDataItem class:
internal class treeDataItem
{
public string Text { get; set; }
public int ID { get; set; }
public int ParentID { get; set; }
public Guid Value { get; set; }
public treeDataItem(int id, int parentId, string text, string value)
{
ID = id;
ParentID = parentId;
Text = text;
Value = value;
}
}
I'm not familiar with the ASP.NET treeview control, so here's a generic solution.
DateTable row
class Foo
{
public string A { get; set; }
public string B { get; set; }
public string C { get; set; }
}
Tree node
class Node
{
private readonly string name;
private readonly Node[] children;
public Node(string name, Node[] children)
{
this.name = name;
this.children = children;
}
}
Recursive algorithm to group rows into nodes
static IEnumerable<Node> Traverse<T, U>(
IEnumerable<T> items,
Func<T, U>[] keySelectors,
int selectorIndex)
{
if (selectorIndex < keySelectors.Length)
{
foreach (var g in items.GroupBy(keySelectors[selectorIndex]))
{
yield return new Node(g.Key.ToString(),
Traverse(g, keySelectors, selectorIndex + 1).ToArray());
}
}
}
Test
var items = new[]
{
new Foo { A = "A1", B = "B1", C = "C1" },
new Foo { A = "A1", B = "B1", C = "C2" },
new Foo { A = "A1", B = "B2", C = "C1" },
new Foo { A = "A1", B = "B2", C = "C2" },
new Foo { A = "A2", B = "B1", C = "C1" },
new Foo { A = "A2", B = "B1", C = "C2" },
new Foo { A = "A2", B = "B2", C = "C1" },
new Foo { A = "A2", B = "B2", C = "C2" },
};
var nodes = Traverse(items, new Func<Foo, string>[]
{
f => f.A,
f => f.B,
f => f.C
}, 0).ToArray();
Output
- A1
- B1
- C1
- C2
- B2
- C1
- C2
- B1
- A2
- B1
- C1
- C2
- B2
- C1
- C2
- B1
I have no expertise in C# but I'd approach a problem like that in two stages:
- Parse the input into something usable.
- Then bind the treeview to it.
Your input data is fairly complex so a custom parser to handle all the special situations is well justified.
string[] data = new string[] {
"Item1 Item1Desc Project1 RoomE Closet-7",
"Item2 Item2Desc Project1 RoomW Closet8",
"Item3 Item3Desc Project1 RoomW Closet8",
"Item4 Item4Desc Project1 RoomN Closet2",
"Item5 Item5Desc Project1 RoomN Closet9",
"Item6 Item6Desc Project2 RoomN Closet2",
"Item7 Item7Desc Project2 RoomW Closet9" };
foreach (string row in data)
{
string[] columns = row.Split(' ');
TreeNodeCollection treeNodes=treeView1.Nodes;
for (int col = 2; col < columns.Length; col++)
{
string column = columns[col];
if (!treeNodes.ContainsKey(column))
{
treeNodes.Add(column, column);
}
TreeNode tn = treeNodes[column];
treeNodes = tn.Nodes;
}
treeNodes.Add(string.Format("{0} - {1}", columns[0], columns[1]));
}
精彩评论