Hi,
I need to use BindingList as DataSource for UltraWinTree. So I have created form with UltraWinTree and wrote some code for filling BindingList to get nested nodes (see pic1. below). Node with "1.2" caption has several nested childs marked from "0" to "9". But when I try to open "0" node, I get the exception: "A first chance exception of type 'System.MissingMethodException' occurred in mscorlib.dll. Additional information: Constructor on type 'MyUltra.ISomeNode' not found." But if I remove source code line which adds node "1.1" everything works fine (see pic2). Why does it happen? Please, see my code below.
Thanks in advance.
pic1
pic2
public interface ISomeNode { string Name { get; set; } BindingList< ISomeNode > Childs { get; set; } }
public class SomeNode : ISomeNode { private readonly BindingList< ISomeNode > _list = new BindingList< ISomeNode >();
public string Name { get; set; }
public BindingList< ISomeNode > Childs { get { return _list; } set {} } }
private void Form1_Load(object sender, EventArgs e) { ultraTree1.ViewStyle = ViewStyle.Standard; BindingList<SomeNode> ds = new BindingList<SomeNode>(); SomeNode root = new SomeNode() { Name = "1" }; ds.Add( root );
SomeNode r1_1 = new SomeNode() { Name = "1.1" }; SomeNode r1_2 = new SomeNode() { Name = "1.2" }; root.Childs.Add( r1_1 ); // Remove this and everything works fine root.Childs.Add( r1_2 );
SomeNode node = r1_2; for( int i = 0; i < 10; i++ ) { node = PutNode( node, i ); }
ultraTree1.SetDataBinding(ds, null); }
private SomeNode PutNode( SomeNode node, int numero ) { SomeNode child = new SomeNode(); child.Name = string.Format( "{0}", numero );
node.Childs.Add( child ); return child; }
Since this is a FirstChanceException, it's being caught, so this may not even be a problem.
But what's most likely happening here is that the BindingManager in DotNet is trying to determine the structure of the data at the third level (for the nodes under the "0" node). If there are actual rows of data there, this is no problem. But if node "0" doesn't have any child nodes, then the BindingManager will attempt to add a new row to the data so that it can examine that row and determine the data structure, then cancel the add.
So what's probably happening here is that the BindingManager is trying to create a new row, but since you are returning a list that contains an interface type or a type that does not have a public parameterless constructor, it cannot do so.
I assume from the name that ISomeNode is an interface. If that's the case, then I strongly advise against using that in a bound data situation. The BindingManager will not work well with an interface, it needs a concrete type.
Another possible option would be to implement IEditableObject on the ISomeNode objects.That will allow the BindingManager to create and then cancel these objects.
For whatever reason, the BindingManager wants to see a parameterless constructor on the classes to which you bind. I don't know the reason why removing that line of code makes a difference.