Why IEnumerable<T> becomes empty after adding elements to a collection? - c#

I have an IEnumerable<T> when I iterate through it and add it's element to a list it becomes empty?
Is there generally anything wrong about what I expect from the code?
public class Apple
{
private ICollection<Fruit> _fruits = new List<Fruit>();
public void AddFruits(IEnumerable<Fruit> fruits)
{
if (fruits == null) throw new ArgumentNullException("fruits");
foreach (var fruit in fruits)
{
_fruits.Add(fruit);
}
}
}
The caller code:
public void AddFruits(IEnumerable<Fruit> fruitsToAdd)
{
foreach (var apple in apples)
{
// Here fruitsToAdd has elements, fruitsToAdd.ToList() has two fruits.
apple.AddFruits(fruitsToAdd);
// Here fruitsToAdd has NO element!!, fruitsToAdd.ToList() is empty!
// next iteration will not add any fruit to next apple since fruitsToAdd is empty.
}
}
Update
The ToList() solved the problem. The root of the problem was that the caller to AddFruits(IEnumerable fruitsToAdd) send fruitsToAdd that was like.
fruitsToAdd = obj.Fruits.Except(apples.Fruits);
Each time IEnumerable fruitsToAdd was Rest it run above statement. Which at next iteration run Except and thereby returned no fruits.
The right way is fruitsToAdd = obj.Fruits.Except(apples.Fruits).ToList(); Since we want one evaluation.

Ok, try this:
public void AddFruits(IEnumerable<Fruit> fruitsToAdd)
{
var fruitsToAddCopy = fruitsToAdd.ToList(); // add just this line
foreach (var apple in apples)
{
apple.AddFruits(fruitsToAddCopy); // and change this
}
}
Without knowing the origin of your fruitsToAdd it's impossible to say more. Some IEnumerable<> can't be re-used. Others can.

I modified your code to get it to compile and wrote a test. Your list does not become empty after copying it's elements into the apples.
using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace ClassLibrary3
{
[TestClass]
public class Class1
{
[TestMethod]
public void test()
{
var fruits = new List<Fruit> {new Fruit(), new Fruit(), new Fruit()};
var lists = AddFruits(fruits);
Assert.IsTrue(fruits.Count == 3);
}
public List<Apple> AddFruits(IEnumerable<Fruit> fruitsToAdd)
{
var apples = new List<Apple>
{
new Apple(),
new Apple()
};
foreach (var apple in apples)
{
apple.AddFruits(fruitsToAdd);
}
return apples;
}
}
public class Fruit
{
}
public class Apple
{
private ICollection<Fruit> _fruits = new List<Fruit>();
public void AddFruits(IEnumerable<Fruit> fruits)
{
if (fruits == null) throw new ArgumentNullException("fruits");
foreach (var fruit in fruits)
{
_fruits.Add(fruit);
}
}
}
}

The code in your question shouldn't exhibit such behavior, so I am presuming you tried to simplify it, but removed a lot of functionality from it.
What looks a bit suspicious is that your _fruits field is of type ICollection<T>. This interface is often used with custom collection implementations. Is it possible that, in the actual code, this field isn't instantiated with a List<T>, but rather with a custom implementation of that interface?
If you have a custom collection implementation, then it is perfectly possible for its Add method to do weird stuff (like removing an item from its previous "parent" collection before adding it to its new "parent"). Tree collections often do such things to simplify moving nodes around.
[Edit]
I am aware that this is not OPs actual problem, but I will nevertheless add an example to demonstrate that a custom collection implementation can in fact modify the input collection when its members are added to a different collection.
Let's say the Fruit class looks like this:
partial class Fruit
{
private ICollection<Fruit> _children;
private Fruit _parent;
public String Name { get; set; }
public Fruit()
{
_children = new FruitCollection(this);
}
public void AddFruits(IEnumerable<Fruit> fruits)
{
foreach (Fruit f in fruits)
_children.Add(f);
}
public int NumberOfChildren
{
get { return _children.Count; }
}
public IEnumerable<Fruit> GetFruits()
{
return _children.ToList();
}
}
And there is a custom collection defined as:
partial class Fruit
{
public class FruitCollection : Collection<Fruit>
{
private readonly Fruit _parent;
public FruitCollection(Fruit parent)
{
_parent = parent;
}
protected override void InsertItem(int index, Fruit item)
{
// item already has a parent?
if (item._parent != null)
{
// remove it from previous parent
item._parent._children.Remove(item);
}
// set the new parent
item._parent = _parent;
base.InsertItem(index, item);
}
// other methods should be overriden in a similar way
}
}
Then the following program:
static void Main(string[] args)
{
List<Fruit> abc = new List<Fruit>()
{
new Fruit() { Name = "a" },
new Fruit() { Name = "b" },
new Fruit() { Name = "c" }
};
Fruit apple = new Fruit() { Name = "apple" };
apple.AddFruits(abc);
Console.WriteLine("{0} has {1} children", apple.Name, apple.NumberOfChildren);
// now try to add apples's children to
// each of the following fruits
List<Fruit> def = new List<Fruit>()
{
new Fruit() { Name = "d" },
new Fruit() { Name = "e" },
new Fruit() { Name = "f" }
};
foreach (Fruit f in def)
{
f.AddFruits(apple.GetFruits());
Console.WriteLine("{0} has {1} children", f.Name, f.NumberOfChildren);
}
Console.Read();
}
Would print:
apple has 3 children
d has 3 children
e has 0 children
f has 0 children
Because apple.GetFruits() will return 0 after the first iteration.
By looking at the custom collection's source, it is hard to realize that _children.Add(f) in AddFruits in fact modifies the fruits previous parent collection.

Related

Auto-initialized property not using overridden setter [duplicate]

using System;
using System.Collections.Generic;
class Parent
{
public Child Child { get; set; }
}
class Child
{
public List<string> Strings { get; set; }
}
static class Program
{
static void Main() {
// bad object initialization
var parent = new Parent() {
Child = {
Strings = { "hello", "world" }
}
};
}
}
The above program compiles fine, but crashes at runtime with Object reference not set to an instance of the object.
If you notice in the above snippet, I have omitted new while initializing the child properties.
Obviously the correct way to initialize is:
var parent = new Parent() {
Child = new Child() {
Strings = new List<string> { "hello", "world" }
}
};
My question is why does the C# compiler not complain when it sees the first construct?
Why is the broken initialization valid syntax?
var parent = new Parent() {
Child = {
Strings = { "hello", "world" }
}
};
It's not broken syntax, it's you who uses an object initializer on a property that's simply not instantiated. What you wrote can be expanded to
var parent = new Parent();
parent.Child.Strings = new List<string> { "hello", "world" };
Which throws the NullReferenceException: you're trying to assign the property Strings contained by the property Child while Child is still null.
Using a constructor to instantiate Child first, takes care of this.
There is nothing wrong with the initialisation, but it's trying to initialise objects that doesn't exist.
If the classes have constructors that create the objects, the initialisation works:
class Parent {
public Child Child { get; set; }
public Parent() {
Child = new Child();
}
}
class Child {
public List<string> Strings { get; set; }
public Child() {
Strings = new List<string>();
}
}
You seem to misunderstand what the collection initializer does.
It is a mere syntactic sugar that converts the list in the braces into a series of calls to Add() method that must be defined on the collection object being initialized.
Your = { "hello", "world" } is therefore has the same effect as
.Add("hello");
.Add("world");
Obviously this will fail with a NullReferenceException if the collection is not created.
The second syntax is valid for readonly properties. If you change the code to initialise the Child and Strings properties in the respective constructors, the syntax works.
class Parent
{
public Parent()
{
Child = new Child();
}
public Child Child { get; private set; }
}
class Child
{
public Child()
{
Strings = new List<string>();
}
public List<string> Strings { get; private set; }
}
static class Program
{
static void Main()
{
// works fine now
var parent = new Parent
{
Child =
{
Strings = { "hello", "world" }
}
};
}
}
Referencing a null can`t always be checked for at compile time. Although the compiler sometimes warns of using a variable before it has been assigned. The compiler works correctly. This is a run-time error.
Note that this syntax can cause some unexpected results and hard-to-spot errors:
class Test
{
public List<int> Ids { get; set; } = new List<int> { 1, 2 };
}
var test = new Test { Ids = { 1, 3 } };
foreach (var n in test)
{
Console.WriteLine(n);
}
You might expect the output to be 1,3, but instead it is:
1
2
1
3

Initializing list property without "new List" causes NullReferenceException

using System;
using System.Collections.Generic;
class Parent
{
public Child Child { get; set; }
}
class Child
{
public List<string> Strings { get; set; }
}
static class Program
{
static void Main() {
// bad object initialization
var parent = new Parent() {
Child = {
Strings = { "hello", "world" }
}
};
}
}
The above program compiles fine, but crashes at runtime with Object reference not set to an instance of the object.
If you notice in the above snippet, I have omitted new while initializing the child properties.
Obviously the correct way to initialize is:
var parent = new Parent() {
Child = new Child() {
Strings = new List<string> { "hello", "world" }
}
};
My question is why does the C# compiler not complain when it sees the first construct?
Why is the broken initialization valid syntax?
var parent = new Parent() {
Child = {
Strings = { "hello", "world" }
}
};
It's not broken syntax, it's you who uses an object initializer on a property that's simply not instantiated. What you wrote can be expanded to
var parent = new Parent();
parent.Child.Strings = new List<string> { "hello", "world" };
Which throws the NullReferenceException: you're trying to assign the property Strings contained by the property Child while Child is still null.
Using a constructor to instantiate Child first, takes care of this.
There is nothing wrong with the initialisation, but it's trying to initialise objects that doesn't exist.
If the classes have constructors that create the objects, the initialisation works:
class Parent {
public Child Child { get; set; }
public Parent() {
Child = new Child();
}
}
class Child {
public List<string> Strings { get; set; }
public Child() {
Strings = new List<string>();
}
}
You seem to misunderstand what the collection initializer does.
It is a mere syntactic sugar that converts the list in the braces into a series of calls to Add() method that must be defined on the collection object being initialized.
Your = { "hello", "world" } is therefore has the same effect as
.Add("hello");
.Add("world");
Obviously this will fail with a NullReferenceException if the collection is not created.
The second syntax is valid for readonly properties. If you change the code to initialise the Child and Strings properties in the respective constructors, the syntax works.
class Parent
{
public Parent()
{
Child = new Child();
}
public Child Child { get; private set; }
}
class Child
{
public Child()
{
Strings = new List<string>();
}
public List<string> Strings { get; private set; }
}
static class Program
{
static void Main()
{
// works fine now
var parent = new Parent
{
Child =
{
Strings = { "hello", "world" }
}
};
}
}
Referencing a null can`t always be checked for at compile time. Although the compiler sometimes warns of using a variable before it has been assigned. The compiler works correctly. This is a run-time error.
Note that this syntax can cause some unexpected results and hard-to-spot errors:
class Test
{
public List<int> Ids { get; set; } = new List<int> { 1, 2 };
}
var test = new Test { Ids = { 1, 3 } };
foreach (var n in test)
{
Console.WriteLine(n);
}
You might expect the output to be 1,3, but instead it is:
1
2
1
3

Foreach loop on a generic list in a class which inherits from a abstract class

(The title is not very good I supposed... feel free to change; I hope I can express myself better with an example)
I have the following classes:
abstract class AbstractObject<T>
{
List<T> Children { get; protected set; }
}
class A : AbstractObject<A>
{
//I have access to a List<A>
}
class B : AbstractObject<B>
{
//I have access to a List<B>
}
Then, at some point I have the following method:
private TreeNode PupulateRecursively<T>(AbstractObject<T> _us)
{
if (_us.Children == null || _us.Children.Count == 0)
{
return new TreeNode(string.Format("{0} - {1}", _us.FormattedID, _us.Name)) { Tag = _us };
}
else
{
Debug.Assert(_us.Children.Count > 0);
TreeNode node = new TreeNode(string.Format("{0} - {1}", _us.FormattedID, _us.Name)) { Tag = _us };
foreach (var child in _us.Children)
{
TreeNode n = PupulateRecursively(child);
node.Nodes.Add(n);
}
return node;
}
}
But I'm getting a: The type arguments for method PupulateRecursively<T> (AbstractRallyObject<T>) cannot be inferred from the usage. Try specifying the type arguments explicitly., because the child var inside the foreach is of type T.
How can I fix this? It is a design issue?
The parameter to PupulateRecursively<T> is an AbstractRallyObject<T> but you're passing in a T:
foreach (var child in _us.Children) // Children is a List<T>
{
TreeNode n = PupulateRecursively(child); //child is a T
you could define Children as a List<AbstractObject<T>> whichi would compile but I don't know enough about your design to know if it's right.
It seems you call your PupulateRecursively method without the generic argument like this :
TreeNode n = PupulateRecursively<T>(child);
It looks like you need to define your collection as List<AbstractObject<T>>
abstract class AbstractObject<T>
{
List<AbstractObject<T>> Children { get; protected set; }
}

Creating a List of Lists in C#

I seem to be having some trouble wrapping my head around the idea of a Generic List of Generic Lists in C#. I think the problem stems form the use of the <T> argument, which I have no prior experience playing with. Could someone provide a short example of declaring a class which is a List, that therein contains another List, but where the type of the object contained therein is not immediately known?
I've been reading through the MS documentation on Generics, and I am not immediately sure if I can declare a List<List<T>>, nor how exactly to pass the <T> parameter to the inside list.
Edit: Adding information
Would declaring a List<List<T>> be considered legal here? In case you are wondering, I am building a class that allows me to use a ulong as the indexer, and (hopefully) steps around the nasty 2GB limit of .Net by maintaining a List of Lists.
public class DynamicList64<T>
{
private List<List<T>> data = new List<List<T>>();
private ulong capacity = 0;
private const int maxnumberOfItemsPerList = Int32.MaxValue;
public DynamicList64()
{
data = new List<List<T>>();
}
A quick example:
List<List<string>> myList = new List<List<string>>();
myList.Add(new List<string> { "a", "b" });
myList.Add(new List<string> { "c", "d", "e" });
myList.Add(new List<string> { "qwerty", "asdf", "zxcv" });
myList.Add(new List<string> { "a", "b" });
// To iterate over it.
foreach (List<string> subList in myList)
{
foreach (string item in subList)
{
Console.WriteLine(item);
}
}
Is that what you were looking for? Or are you trying to create a new class that extends List<T> that has a member that is a `List'?
or this example, just to make it more visible:
public class CustomerListList : List<CustomerList> { }
public class CustomerList : List<Customer> { }
public class Customer
{
public int ID { get; set; }
public string SomethingWithText { get; set; }
}
and you can keep it going. to the infinity and beyond !
A list of lists would essentially represent a tree structure, where each branch would constitute the same type as its parent, and its leaf nodes would represent values.
Implementation
public sealed class TreeList<T> : List<TreeList<T>>
{
public List<T> Values { get; } = new List<T>();
public TreeList<T> this[int index]
{
get
{
while (index > Count - 1)
{
Branch();
}
return base[index];
}
}
public TreeList<T> Branch()
{
TreeList<T> result = new TreeList<T>();
Add(result);
return result;
}
}
Example
internal static class Program
{
public static void Main()
{
// Create the root element...
TreeList<string> treeList = new TreeList<string>();
// You can add branches the old-fashioned way...
treeList.Add(new TreeList<string>());
// Add leaf node values to your first branch...
treeList[0].Values.Add("Hello, World!");
treeList[0].Values.Add("Goodbye, World!");
// You can create new branches from any branch like this...
// Note: You could also chain branch statements; i.e. treeList.Branch().Branch().Branch()
TreeList<string> branch2 = treeList.Branch();
// Add leaf node values to your second branch...
branch2.Values.Add("Alice");
branch2.Values.Add("Bob");
// You can also create branches until you reach the desired branch index...
// The TreeList indexer will loop until the desired index has been created, and then return it.
treeList[7].Values.Add("Alpha");
treeList[7].Values.Add("Bravo");
treeList[7].Values.Add("Charlie");
// How many branches does the root have?
Console.WriteLine($"Treelist branches: {treeList.Count}");
// What's at branch 0's values?
foreach (string value in treeList[0].Values)
{
Console.WriteLine(value);
}
// What's at branch 1's values?
foreach (string value in treeList[1].Values)
{
Console.WriteLine(value);
}
// What's at branch 7's values?
foreach (string value in treeList[7].Values)
{
Console.WriteLine(value);
}
}
}
Now, whether you should implement something like this is another matter. Extending List<T> isn't recommended: Why not inherit from List<T>?
public class ListOfLists<T> : List<List<T>>
{
}
var myList = new ListOfLists<string>();
I have the following code
public class ChildClass
{
public string FieldName { get; set; }
public string Value { get; set; }
public string StatusClass { get; set; }
public string StatusMessage { get; set; }
}
Creating a list of list obj is as follows
List<List<ChildClass>> obj = new List<List<ChildClass>>();
Look a direct example here:
public partial class Form1 : Form
{
List<List<Label>> txtList;
List<List<int>> num;
public Form1()
{
InitializeComponent();
txtList = new List< List<Label> >() {
new List<Label> { label1, label2, label3 },
new List<Label> { label4, label5, label6 },
new List<Label> { label7, label8, label9 }
};
num = new List<List<int>>() { new List<int>() { 1, 2 }, new List<int>() { 3, 4 } };
}
}
you should not use Nested List in List.
List<List<T>>
is not legal, even if T were a defined type.
https://msdn.microsoft.com/en-us/library/ms182144.aspx

Populate a TreeView from an object

I am having a problem with a treeview in my WinForm app. I created a TreeViewItem class that holds the data. There are only 5 fields: CaseNoteID, ContactDate, ParentNoteID, InsertUser, ContactDetails.
public class TreeItem
{
public Guid CaseNoteID;
public Guid? ParentNoteID;
public string ContactDate;
public string InsertUser;
public string ContactDetails;
public TreeItem(Guid caseNoteID, Guid? parentNoteID, string contactDate, string contactDetails, string insertUser)
{
CaseNoteID = caseNoteID;
ParentNoteID = parentNoteID;
ContactDate = contactDate;
ContactDetails = contactDetails;
InsertUser = insertUser;
}
}
The plan was to show relationships of the notes by showing a note under it's parent as determined by the ParentNoteID field. Pretty simplistic really. Unfortunately, all my attempts so far have put a "child" note, one with a ParentNoteID, in both positions. The first level AND under it's appropriate Parent.
When I step through my code my data is coming back accurately.
List<TreeItem> items = BLLMatrix.GetTreeViewData(HUD.PersonId);
PopulateTree(tvwCaseNotes,items);
I just don't know how to take that and populate my TreeView accurately with it. This is what I started but now I am stuck.
public static void PopulateTree(TreeView tree, ICollection<TreeItem> items)
I just don't seem able to wrap my head around it. Do I need to split my data call up and first return all entrys with ParentNoteID = null and then go get the rest and somehow join the two?
#Hogan: I apologize for the drastic change in the question. It was evident from your response that I hadn't approached this from a good angle in the first place. In the second place, the original method still did not work.
Maybe i completely misunderstood you, but you have a flat hierarchy where each element knows its parent. Now you have to create each element and afterwards built up the hierarchy. Here is a first quick shot of such an implementation (missing cyclic checks, error handling, etc.):
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
PopulateTreeView(treeView, SampleData());
}
private IEnumerable<Item> SampleData()
{
yield return new Item { CaseID = "1" };
yield return new Item { CaseID = "2" };
yield return new Item { CaseID = "3" };
yield return new Item { CaseID = "4", ParentID = "5" };
yield return new Item { CaseID = "5", ParentID = "3" };
yield return new Item { CaseID = "6" };
yield return new Item { CaseID = "7", ParentID = "1" };
yield return new Item { CaseID = "8", ParentID = "1" };
}
private void PopulateTreeView(TreeView tree, IEnumerable<Item> items)
{
Dictionary<string, Tuple<Item, TreeNode>> allNodes = new Dictionary<string, Tuple<Item, TreeNode>>();
foreach (var item in items)
{
var node = CreateTreeNode(item);
allNodes.Add(item.CaseID, Tuple.New(item, node));
}
foreach (var kvp in allNodes)
{
if (kvp.Value.First.ParentID != null)
{
allNodes[kvp.Value.First.ParentID].Second.Nodes.Add(kvp.Value.Second);
}
else
{
tree.Nodes.Add(kvp.Value.Second);
}
}
}
private TreeNode CreateTreeNode(Item item)
{
var node = new TreeNode();
node.Text = item.CaseID;
return node;
}
}
public class Item
{
public string CaseID { get; set; }
public string ParentID { get; set; }
}
public class Tuple<T>
{
public Tuple(T first)
{
First = first;
}
public T First { get; set; }
}
public class Tuple<T, T2> : Tuple<T>
{
public Tuple(T first, T2 second)
: base(first)
{
Second = second;
}
public T2 Second { get; set; }
}
public static class Tuple
{
//Allows Tuple.New(1, "2") instead of new Tuple<int, string>(1, "2")
public static Tuple<T1> New<T1>(T1 t1)
{
return new Tuple<T1>(t1);
}
public static Tuple<T1, T2> New<T1, T2>(T1 t1, T2 t2)
{
return new Tuple<T1, T2>(t1, t2);
}
}
What is a Tuple?
Just to answer the question in the comment:
Take a look at Wikipedia.
Take a look at this StackOverflow question.
It is a simple container object holding two other objects. That's it.
I used it, cause in my Dictionary is a unqiue identifier (string CaseID) which references on two objects (TreeNode and Item). Another approach would be to make two Dictionaries as Dictionary<string, TreeNode> and Dictionary<string, Item>, but because there is a 1:1 relationship i took the tuple approach.
Maybe rename it to ItemTreeNodeContainer and it will get more clearer for you what it means in the concrete situation.
The basic idea of recursion is you use the stack as a temporary store for variables on each call. However, you are referencing a global variable in your recursive call. When you change it (via the filter function) it will invalidate all prior calls in the recursion. You need to remove the recursion or push a new copy (and not a reference like you are doing) of the control variable (the rows) on the stack.
edit based on comment
I hate putting code out there without being able to test it, but I believe something like this should work to solved the problem I described.
Here is the problem area:
// using the Find method uses a Predicate generic delegate.
if (nodeList.Find(FindNode) == null)
{
var tmpCNoteID = dr["CaseNoteID"].ToString();
var filter = "ParentNote='" + tmpCNoteID + "'";
DataRow[] childRows = cNoteDT.Select(filter);
if (childRows.Length > 0)
{
// Recursively call this function for all childRows
TreeNode[] childNodes = RecurseRows(childRows);
// Add all childnodes to this node
node.Nodes.AddRange(childNodes);
}
// Mark this noteID as dirty (already added)
nodeList.Add(node);
}
Something like this should fix the problem I see (note: this is not elegant or good code, it is just a fix to the problem I describe above, I would never put my name to this code). Also, without being able to test the code I can't even be sure this is the problem.
// using the Find method uses a Predicate generic delegate.
if (nodeList.Find(FindNode) == null)
{
var tmpCNoteID = dr["CaseNoteID"].ToString();
var filter = "ParentNote='" + tmpCNoteID + "'";
DataTable DTCopy = cNoteDT.Copy()
DataRow[] childRows = DTCopy.Select(filter);
if (childRows.Length > 0)
{
// Recursively call this function for all childRows
TreeNode[] childNodes = RecurseRows(childRows);
// Add all childnodes to this node
node.Nodes.AddRange(childNodes);
}
// Mark this noteID as dirty (already added)
nodeList.Add(node);
}
Solved my problem using Oliver's solution. Just refactored it using Tuple that part of .Net 4.0
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
PopulateTreeView(treeView1, SampleData());
}
private IEnumerable<Item> SampleData()
{
yield return new Item { CaseID = "1" };
yield return new Item { CaseID = "2" };
yield return new Item { CaseID = "3" };
yield return new Item { CaseID = "4", ParentID = "5" };
yield return new Item { CaseID = "5", ParentID = "3" };
yield return new Item { CaseID = "6" };
yield return new Item { CaseID = "7", ParentID = "1" };
yield return new Item { CaseID = "8", ParentID = "1" };
}
private void PopulateTreeView(TreeView tree, IEnumerable<Item> items)
{
Dictionary<string, Tuple<Item, TreeNode>> allNodes = new Dictionary<string, Tuple<Item, TreeNode>>();
foreach (var item in items)
{
var node = CreateTreeNode(item);
allNodes.Add(item.CaseID, Tuple.Create(item, node));
}
foreach (var kvp in allNodes)
{
if (kvp.Value.Item1.ParentID != null)
{
allNodes[kvp.Value.Item1.ParentID].Item2.Nodes.Add(kvp.Value.Item2);
}
else
{
tree.Nodes.Add(kvp.Value.Item2);
}
}
}
private TreeNode CreateTreeNode(Item item)
{
var node = new TreeNode();
node.Text = item.CaseID;
return node;
}
}
public class Item
{
public string CaseID { get; set; }
public string ParentID { get; set; }
}
Tuple Help on MSDN:
Tuple Class
In my case I'm passing data source from entity framework: Entities.Categories
and replaced Item class with Category class generated by entity framework.

Categories

Resources