Hello,
Mainly I can't understand why I don't see node (Level 3) in case "wrong" in test example?
Cases wrong and right differ only of their order of nodes.
And one more question.
If i remove line 49
(ultraTreeNodeColumn1.DataType = typeof(string);)
in file Form1.Designer.cs
the tree looks like list
How it related with type of column?
I am using Infragistics2.Win.UltraWinTree.v10.3.dll (version 10.3.20103.1000)
Thank you
Roman
Hello Roman,
Setting the datasource to null prior should not impact the sample or required for that matter. Please make sure you are using the latest service release if you cannot upgrade to our latest ( 14.2. )
Installing the latest service release for Infragistics helps keep your application up to date for the version used. For information on how to get the latest service release, see "How to get the latest service release" http://ko.infragistics.com/community/forums/t/29398.aspx
For general information about service packs, see our Service Release Schedule http://ko.infragistics.com/support/service-releases
Let me know if you have any questions regarding this matter.
Thank you Mike!
It seems it works now. So I missed only creating of children collection in default constructor.
One more thing I should add. It is to set null in ultraTree1.DataSource before set data.
this.ultraTree1.DataSource = null;this.ultraTree1.DataSource = nodes;
Else, your example doesn't work for me again.May be it is because of different versions.
Mike Saltzman said:I was passing the array of nodes into the constrcutor of the new BindingList of Children
Mike, BindingList doesn't have constructor that eats any array.
Best regards
Hi Roman,
Okay, I got it working. I am attaching a small sample project here that works correctly.
There were several key factors, some of which I already mentioned.
First, your Node object has to have a parameterless constructor so that the BindingManager can add (and Cancel) an item when there are no items on the list.
As I mentioned, after that, I was getting an error that the collection is read-only. This was caused by the code that was populating the child collection in your constructor. I was passing the array of nodes into the constrcutor of the new BindingList of Children, but since the array cannot be added to, that means the collection cannot be added to. So this was simply a matter of creating the children BindingList and then looping through the array to add the items.
Hi Mike,
I didn't set list to array, but it doesn't matter.
I tried some things and found one case when my case works fine.
(I should use BindingList and I should support default constructor Node())
But I caught some error later.
It is not important for my task because I use static datasource.
But please check if it is bug of infragistics or not.
using System;using System.ComponentModel;using System.Linq;using System.Windows.Forms;using Infragistics.Win.UltraWinTree; namespace UltraTreeDepthTest{ public partial class Form1 : Form { public Form1() { InitializeComponent();RadioButtonCheckedChanged(radioButton1, EventArgs.Empty); RadioButtonCheckedChanged(radioButton1, EventArgs.Empty); RadioButtonCheckedChanged(radioButton1, EventArgs.Empty); } private readonly Node node0 = new Node("Node (no children)"); private readonly Node node1 = new Node("Node (level 1)", new Node("Node (level 2)", new Node("Node (level 3)"))); private void RadioButtonCheckedChanged(object sender, EventArgs e) { ultraTree1.DataMember = "Children"; ultraTree1.DataSource = radioButton1.Checked ? new Node("root", node0, node1) : new Node("root", node1, node0); ultraTree1.ExpandAll(ExpandAllType.Always); } } public class Node { public Node() { } public Node(string text, params Node[] children) { Text = text; this.children = new BindingList<Node>(children.ToList()); } public string Text { get; private set; } private readonly BindingList<Node> children; public BindingList<Node> Children { get { return children; } } }}
using System;using System.ComponentModel;using System.Linq;using System.Windows.Forms;using Infragistics.Win.UltraWinTree;
namespace UltraTreeDepthTest{ public partial class Form1 : Form { public Form1() { InitializeComponent();RadioButtonCheckedChanged(radioButton1, EventArgs.Empty); RadioButtonCheckedChanged(radioButton1, EventArgs.Empty); RadioButtonCheckedChanged(radioButton1, EventArgs.Empty); }
private readonly Node node0 = new Node("Node (no children)");
private readonly Node node1 = new Node("Node (level 1)", new Node("Node (level 2)", new Node("Node (level 3)")));
private void RadioButtonCheckedChanged(object sender, EventArgs e) { ultraTree1.DataMember = "Children"; ultraTree1.DataSource = radioButton1.Checked ? new Node("root", node0, node1) : new Node("root", node1, node0); ultraTree1.ExpandAll(ExpandAllType.Always); } }
public class Node { public Node() { }
public Node(string text, params Node[] children) { Text = text; this.children = new BindingList<Node>(children.ToList()); }
public string Text { get; private set; }
private readonly BindingList<Node> children;
public BindingList<Node> Children { get { return children; } } }}
notice that I set datasource 3 times!
In this case empty node appears.
Empty child is appeared:
If yo will delete duplicated RadioButtonCheckedChanged(radioButton1, EventArgs.Empty);
everything will be ok for the first time, but you can see this behaviour if you will to change wrong and right several times.
I think it is related problem. I very hope you will find and fix it and it will fix original issue.
About datatypes.
I don't want to use automatically ColumnSets. It can show me columns that I don't need.
I commented just 1 line in example and you can see it on screenshot:
The code you have here won't compile because you are setting your List<Node> to an array. But anyway, I fixed that and changed Children to a BindingList<Node> (which is a much better data source for binding) and I still get the same results.
My original explanation was incomplete. Here's what's happening:
1) You bind the tree to the Children of the Root node.
2) There are two child nodes in this list (Node0, and Node1). Since the list is not null and has items in it, the BindingManager is able to get the data structure, no problem.
3) The tree can see that this data structure includes a Children property which is of type BindingList<Node>. Since it knows the items in the list are Nodes, it has no problem getting the data structure for level 2 (the children of Node0/Node1).
4) But that's the end of the chain. Once you get to that point, the root-level node has no more nodes in the hierarchy. So the binding manager can't get a node at level 2, it cannot know what the structure of the level 3 nodes is - or that there even exists a level 3.
Just to be clear once again - this has nothing to do with the WinTree control. It's a limitation of the BindingManager in DotNet.
In order for this to work, you would have to set up your data source in such a way that the BindingManager could add a node under Node0 and then cancel it. This is tricky. In order to add a node, you Node object needs a parameterless constructor.Your current Node object requires parameters so the BindingManager cannot add one to the collection.
I fixed that, but I'm still not able to get this to work. For some reason, when the BindingManager tries to add a node to the third level, it's blowing up with an exception that the collection is read-only. I will have to look into this a little more and see if I can figure out what's going on. I know there have been many posts about the same issue in the past.
Regarding the DataType, I'm afraid I don't understand what you are asking. Why would you set the DataType on the column? The tree is creating the ColumnSets automatically with the correct types.