RadTreeView binds to Object-relational data and can see the treeview, but the tree and Nodes are empty

1 Answer 104 Views
Treeview
Suhaib
Top achievements
Rank 1
Iron
Suhaib asked on 10 Oct 2023, 02:37 PM | edited on 10 Oct 2023, 02:43 PM

In my application, I'm able to bind a TreeView to a Well object in my application through object-relational binding as such:

this.wellTreeView = new RadTreeView();

BindingList<Well> wells = new BindingList<Well>() { well }; this.wellTreeView.DataSource = wells; this.wellTreeView.DisplayMember = "name\\name\\name"; this.wellTreeView.ChildMember = "wells\\layers\\items";

This works and I am able to view the TreeView hierarchy and select the nodes in the form. However, when trying to get the nodes in code, the wellTreeView is empty (0 nodes) and throws an Index out of range error in:

RadTreeNode node = wellTreeView.Nodes[0];

My Well class is defined like so:

public class Well
{
    public string name {get; set;}
    public List<Layer> layers {get; set;}
}

public class Layer
{
    public string name {get; set;};
    public List<Item> items {get; set;}
}

public class Item
{
    public string name {get; set;};
    public decimal length {get; set;}
}

I don't understand why the wellTreeView is empty without any nodes despite being able to view the tree in the form. Surely the well is bound to the TreeView?



1 Answer, 1 is accepted

Sort by
1
Accepted
Dinko | Tech Support Engineer
Telerik team
answered on 11 Oct 2023, 12:38 PM

Hi Suhaib,

Thank you for the provided code snippet.

I have tested your approach but the Nodes collection is populated on my side. I am not sure at what point you want to get the first node from the collection. Probably the collection is still not populated at that moment. Can you check the attached project and let me know what I am missing from your set-up? When you run the project click on the button. In the event handler, I am getting the first node from the Nodes collection.

I am looking forward to your reply.

Regards,
Dinko | Tech Support Engineer
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Suhaib
Top achievements
Rank 1
Iron
commented on 11 Oct 2023, 02:31 PM | edited

Hi Dinko,

Thank you for getting back to me.

Your project works fine. My problem is still there though. At what point is collection populated completely?  I'm not using a button. Instead I'm trying to access the node after binding the DataSource in order to select the first Node(i.e. root), whose properties I will use to fill up controls in a Panel. All my controls are built programmatically without using the Designer. The Well object is passed from another form.

Another question I had was how would I add to the Tag of the Node during binding?

Additional code:

public partial class FrmWellEditor : Telerik.WinControls.UI.RadForm
{
    private RadTreeView wellTreeView;

    public FrmWellEditor(Well well)
    {
        InitializeComponent();  // auto generated code - unmodified
        InitializeEditor();     // initialise controls i.e. TreeView, Panels, Size, Location etc
        BindWellToTree(well);
        NodeSelect();
    }

    private void InitializeEditor()
    {
        // 
        this.wellTreeView = new RadTreeView();
        //
    }

    private void BindWellToTree(well)
    {
        BindingList<Well> wells = new BindingList<Well>() { well };
        this.wellTreeView.DataSource = wells;
        this.wellTreeView.DisplayMember = "name\\name\\name";
        this.wellTreeView.ChildMember = "wells\\layers\\items";
    }

    private void NodeSelect()
    {
        // 
        RadTreeNode node = this.wellTreeView.Nodes[0];
        //
    }
}

Dinko | Tech Support Engineer
Telerik team
commented on 12 Oct 2023, 11:43 AM

Thank you for the provided code snippet.

I see the problem here. When the RadTreeView is created at run time, note that it is important to initialize its BindignContext property before setting the DataSource property. Otherwise, the control will be empty as seen in this particular case.

private void InitializeEditor()
{
    // 
    this.wellTreeView = new RadTreeView();
    wellTreeView.BindingContext = new BindingContext();
    //
}

This should work now.

Suhaib
Top achievements
Rank 1
Iron
commented on 12 Oct 2023, 01:12 PM | edited

Hi Dinko,

Yes that worked.

I was also able to make it work by calling LoadElementTree() after binding with the DataSource (without initialising its BindingContext):

BindingList<Well> wells = new BindingList<Well>() { well };

this.wellTreeView.DataSource = wells;
this.wellTreeView.DisplayMember = "name\\name\\name";
this.wellTreeView.ChildMember = "wells\\layers\\items";

this.wellTreeView.LoadElementTree();

Why was I able to make it work by calling LoadElementTree() without providing the BindingContext? 

I cannot find any mention of "BindingContext" or "LoadElementTree()" in the TreeView documentation. I genuinely feel that the documentation can be improved with more explanation and scenarios (e.g. in this case where I am doing it at run time)

 

Also, how do I add to the TreeNode Tag during the binding process?

Thanks for your help!

 
Dinko | Tech Support Engineer
Telerik team
commented on 13 Oct 2023, 01:33 PM

This behavior is not directly related to our controls. It's framework-specific. When the LoadElementTree() method is called it will set the BindingContext internally. Additional information about the BindingContext and how to use it is available in the following MSDN articles:

As for your second question, I am not sure what you mean by adding a node during the binding process. Basically, you could add Well object to the wells collection which is set to the DataSource of the RadTreeView. The collection will raise collection change notifications and the new object will be reflected in the control.

Suhaib
Top achievements
Rank 1
Iron
commented on 13 Oct 2023, 01:50 PM

I don't mean that I want to add a node during binding.

I mean, when I provide the DataSource to the TreeView, I also provide the DisplayMember, ChildMember etc. Is there a way to specify the Tag property of each TreeNode in the TreeView? The Tag property could be a value from the well object.

There are similar questions on your forums about the Tag property:

https://www.telerik.com/forums/tag-property-and-databinding

https://www.telerik.com/forums/does-telerik-radtreenode-have-some-sort-of-tag-property

Dinko | Tech Support Engineer
Telerik team
commented on 16 Oct 2023, 11:19 AM

Thank you for elaborating your question. In this case, you can try subscribing to the NodeDataBound event. In the event handler you can get the Node, check its type, and set its Tag property per your requirement.

private void WellTreeView_NodeDataBound(object sender, RadTreeViewEventArgs e)
{
    if (e.Node.DataBoundItem is Well)
    {
        var well = e.Node.DataBoundItem as Well;
        var name = well.name;
        e.Node.Tag = "Custom Logic";
    }  
}

Suhaib
Top achievements
Rank 1
Iron
commented on 18 Oct 2023, 08:06 AM

Thanks Dinko!
Tags
Treeview
Asked by
Suhaib
Top achievements
Rank 1
Iron
Answers by
Dinko | Tech Support Engineer
Telerik team
Share this question
or