I know this must be real easy but I just can't get it to work... I am trying to make a List for extjs Tree by comparing two columns from differnt rows and putting them as a Node or a leaf accordingly. this is my sample data
ListA ListB labelName
NY Parent1
NY Leaf1
HI Parent2
AK Parent3
and this is my c# end... so when I match NY, I am supposed to have Parent1 as node and Leaf1 as its leaf and not for HI or AK... but doing this throws me all data as Parent.. even the leaf.
SqlCommand cmd = con.CreateCommand();
comd.CommandText = "SELECT * FROM myTable";
con.Open();
SqlDataReader reader = comd.ExecuteReader();
while (reader.Read())
{
City MyData = new City();
MyData.ListA = reader["ListA"].ToString().Trim();
MyData.ListB = reader["ListB"].ToString().Trim();
MyData.labelName = reader["labelName"].ToString().Trim();
giveData.Add(MyData);
}
int count = 1;
List<TreeNode> myNode = new List<TreeNode>();
foreach (City MyData in giveData)
{
// 1st foreach
if (MyData.ListA != "")
{
TreeNode treeNode = new TreeNode();
treeNode.id = count++;
treeNode.name = MyData.labelName;
treeNode.leaf = false;
List<TreeNode> Level1 = new List<TreeNode>();
foreach (City labelName in giveData)
{
if (labelName.ListA == labelName.ListB)
{// 2nd foreach
TreeNode node1 = new TreeNode();
node1.id = count++;
node1.name = labelName.labelName;
node1.leaf = true;
Level1.Add(node1);
}
}
treeNode.children = Level1;
myNode.Add(treeNode);
}
}
return JsonConvert.SerializeObject(myNode);
Should I use array to store each record and compare them instead... I am out of ideas... I am sure there is a better way to accomplish this... Please help
Interface TreeNode. Defines the requirements for an object that can be used as a tree node in a JTree. Implementations of TreeNode that override equals will typically need to override hashCode as well.
The TreeNode label is set by setting the Text property explicitly. The alternative is to create the tree node using one of the TreeNode constructors that has a string parameter that represents the Text property. The label is displayed next to the TreeNode image, if one is displayed.
Solution 1Use TreeView. SelectedNode[^] property, which get or set selected node for currently selected Treeview. If no TreeNode is currently selected, the SelectedNode property is a null reference (Nothing in Visual Basic).
To add nodes programmatically Use the Add method of the tree view's Nodes property.
Assuming the data is the way you state and the "parents" will come before any leaves, here's a single pass way I came up with to create the tree:
[Irrelevant Code Snipped]
Update: LINQ using Dictionary<string, List<TreeNode>>
I created a new class TreeNode and some sample data for testing:
var MyData = new List<City>
{
new City {ListA = "AK", ListB = "", labelName = "Alaska"},
new City {ListA = "HI", ListB = "", labelName = "Hawaii"},
new City {ListA = "", ListB = "HI", labelName = "Hawaii Leaf 1"},
new City {ListA = "", ListB = "HI", labelName = "Hawaii Leaf 2"},
new City {ListA = "NY", ListB = "", labelName = "New York"},
new City {ListA = "", ListB = "NY", labelName = "New York Leaf 1"},
new City {ListA = "", ListB = "NY", labelName = "New York Leaf 2"}
};
Here's the new method that basically creates 2 lists, 1 for the parents and 1 for the leaves. I then loop through the leaves to find any matching parents and add the leaves to it:
var index = 0;
var parents = (from p in MyData
where p.ListB == ""
select p).ToDictionary(p => p.ListA, p => new TreeNode { id = index++, name = p.labelName, leaf = false });
var leaves = (from l in MyData
where l.ListA == ""
group l by l.ListB into stateGroup
select stateGroup).ToDictionary(g => g.Key, g => g.ToList());
foreach (var leaf in leaves.Where(leaf => parents.ContainsKey(leaf.Key)))
{
parents[leaf.Key].children =
leaf.Value.Select(l => new TreeNode {id = index++, name = l.labelName, leaf = true}).ToList();
}
var myNode = parents.Select(p => p.Value).ToList();
return JsonConvert.SerializeObject(myNode);
I think this should be more efficient than using lists and the List.Find()
Your best bet would probably be Linq - I created a quick and dirty VB.Net solution to move you in the right direction - The main part being the SECOND Linq statement...
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim x As New List(Of City)
x.Add(New City With {.ListA = "NY", .ListB = "", .Leaf = "Parent1"})
x.Add(New City With {.ListA = "", .ListB = "NY", .Leaf = "Leaf1"})
x.Add(New City With {.ListA = "HI", .ListB = "", .Leaf = "Parent2"})
x.Add(New City With {.ListA = "AK", .ListB = "", .Leaf = "Parent3"})
tv1.Nodes.AddRange((From y In x Where y.ListA <> "" Select New TreeNode With {
.Name = y.ListA,
.Text = y.Leaf}).ToArray)
For Each nd As TreeNode In tv1.Nodes
Dim Nm As String = nd.Name
nd.Nodes.AddRange((From y In x Where y.ListB = Nm Select New TreeNode(y.Leaf)).ToArray)
Next
End Sub
Simply put, you populate the first ste of parent nodes, then you just loop through all the nodes and populate them with any nodes where ListB = Node's name.
Hope this helps move you in the right direction
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With