I have a situation where I want to create a treeview that has 4 levels. I want to immediately load the first two levels, and only load levels 3 and 4 for a particular level 2 node when it is expanded. I would like all of these nodes to be bound to a datatable(s) for ease of updating the data. What would be the best way to accomplish this? I am experimenting with both related tables in a hierarchy, and a self-referencing table, but haven't seen the exact results I am looking for. Thanks for your help!
13 Answers, 1 is accepted
0
Richard Slade
Top achievements
Rank 2
answered on 10 Nov 2010, 05:32 PM
Hello Sonya,
You can use the LoadOnDemand feature of the RadTreeView for all child nodes, and get the child nodes that you need from the database as the NodeExpandedChanged event is firing.
For more information, please refer to this documentation link
Hope that helps
Richard
You can use the LoadOnDemand feature of the RadTreeView for all child nodes, and get the child nodes that you need from the database as the NodeExpandedChanged event is firing.
For more information, please refer to this documentation link
Hope that helps
Richard
0
Sonya L
Top achievements
Rank 1
answered on 10 Nov 2010, 05:50 PM
Is there a way to have the child nodes (levels 3 and 4) bound to a datatable, rather than creating them manually, as in the example?
0
Richard Slade
Top achievements
Rank 2
answered on 10 Nov 2010, 05:59 PM
Hello Sonya,
As far as I'm aware, you cannot mix bound and unbound modes in this control. You would need to create them all manually, though you could get the levels 3 and 4 from the database and iterate over a reader or object collection that had been brought in from the database.
hope this helps
Richard
As far as I'm aware, you cannot mix bound and unbound modes in this control. You would need to create them all manually, though you could get the levels 3 and 4 from the database and iterate over a reader or object collection that had been brought in from the database.
hope this helps
Richard
0
Emanuel Varga
Top achievements
Rank 1
answered on 10 Nov 2010, 06:20 PM
Hello Sonya,
I would suggest something different, to use some middle tier logic, more precisely a binding list, and load all the data from the db in that binding list, please take a look at the following example:
Basically here, I'm loading the first 2 levels, and after that on node expand just get the data from the db and add it to the list.
Hope this helps, if you have any other questions or comments, please let me know,
Best Regards,
Emanuel Varga
I would suggest something different, to use some middle tier logic, more precisely a binding list, and load all the data from the db in that binding list, please take a look at the following example:
using
System;
using
System.ComponentModel;
using
System.Windows.Forms;
using
Telerik.WinControls.UI;
namespace
TreeViewLazyLoad
{
public
partial
class
Form1 : Form
{
private
RadTreeView radTreeView1;
private
NodesList nodes;
public
Form1()
{
InitializeComponent();
this
.Controls.Add(radTreeView1 =
new
RadTreeView());
radTreeView1.Dock = DockStyle.Fill;
}
protected
override
void
OnLoad(EventArgs e)
{
base
.OnLoad(e);
radTreeView1.LoadOnDemand =
true
;
radTreeView1.NodeExpandedChanged +=
new
RadTreeView.TreeViewEventHandler(radTreeView1_NodeExpandedChanged);
nodes =
new
NodesList();
nodes.GetFirstLevel();
nodes.GetSecondLevel();
radTreeView1.DataSource = nodes;
radTreeView1.ParentIDMember =
"ParentId"
;
radTreeView1.ValueMember =
"Id"
;
radTreeView1.DisplayMember =
"Name"
;
}
void
radTreeView1_NodeExpandedChanged(
object
sender, RadTreeViewEventArgs e)
{
if
(e.Node.Nodes.Count == 0)
{
var node = e.Node.DataBoundItem
as
Node;
nodes.GetChildNodesForNode(node.Id);
}
}
}
public
class
Node
{
public
int
Id
{
get
;
set
;
}
public
int
ParentId
{
get
;
set
;
}
public
string
Name
{
get
;
set
;
}
}
public
class
NodesList : BindingList<Node>
{
public
NodesList()
{
}
public
void
GetFirstLevel()
{
for
(
int
i = 0; i < 4; i++)
{
this
.Add(
new
Node
{
Id = i,
Name =
"Name"
+ i,
ParentId = i
});
}
}
public
void
GetSecondLevel()
{
for
(
int
i = 4; i < 8; i++)
{
this
.Add(
new
Node
{
Id = i,
Name =
"Name"
+ i,
ParentId = i - 4
});
}
}
public
void
GetChildNodesForNode(
int
id)
{
var startIndex =
this
.Count;
for
(
int
i = startIndex; i < startIndex + 4; i++)
{
this
.Add(
new
Node
{
Id = i,
Name =
"Name"
+ i,
ParentId = id
});
}
}
}
}
Basically here, I'm loading the first 2 levels, and after that on node expand just get the data from the db and add it to the list.
Hope this helps, if you have any other questions or comments, please let me know,
Best Regards,
Emanuel Varga
0
Richard Slade
Top achievements
Rank 2
answered on 10 Nov 2010, 06:23 PM
Hi All,
I agree. I hadn't thought of that and beleive that this solution should work well for your scenario
All the best
Richard
I agree. I hadn't thought of that and beleive that this solution should work well for your scenario
All the best
Richard
0
Sonya L
Top achievements
Rank 1
answered on 10 Nov 2010, 07:04 PM
I'll try that, thanks!
0
Emanuel Varga
Top achievements
Rank 1
answered on 10 Nov 2010, 07:06 PM
Glad to be able to help,
If you have any more questions please just let me know, and if the question has been solved, please mark the question as answered, so that others can find the answers to their questions faster.
Best Regards,
Emanuel Varga
If you have any more questions please just let me know, and if the question has been solved, please mark the question as answered, so that others can find the answers to their questions faster.
Best Regards,
Emanuel Varga
0
Sonya L
Top achievements
Rank 1
answered on 11 Nov 2010, 08:02 PM
This example seems to work well, thanks! Now I am trying to clear out the Binding List, and reload it based on a user action, but the tree does not display anything. When the app first loads, I load the Binding List as in the example, and it works fine. When I want to change the contents of the list, I set the tree's datasource to Nothing, clear the list, reload the binding list, and rebind it to the tree. When I do this, the tree is blank. What could I be missing? Thanks!
0
Emanuel Varga
Top achievements
Rank 1
answered on 11 Nov 2010, 10:36 PM
Hello Sonya,
Why are you clearing the list? Why are you setting the datasource to nothing(null)?
Because it is a bindinglist, it will notify the tree on changes so you don't have to remove the datasource, just change the data inside the bindinglist.
Hope this helps, if you have any other questions or comments, please let me know,
Best Regards,
Emanuel Varga
Telerik WinForms MVP
Why are you clearing the list? Why are you setting the datasource to nothing(null)?
Because it is a bindinglist, it will notify the tree on changes so you don't have to remove the datasource, just change the data inside the bindinglist.
Hope this helps, if you have any other questions or comments, please let me know,
Best Regards,
Emanuel Varga
Telerik WinForms MVP
0
Sonya L
Top achievements
Rank 1
answered on 11 Nov 2010, 11:41 PM
I want to show a different tree, that is why I am clearing the list. Basically, the user can pick different 'views' of the data, so the tree has to change entirely.
0
Accepted
Emanuel Varga
Top achievements
Rank 1
answered on 11 Nov 2010, 11:57 PM
Hello again,
Based on what you were saying I've updated the example, please tell me if something should be different:
Hope this helps, if you have any other questions or comments, please let me know,
Best Regards,
Emanuel Varga
Telerik WinForms MVP
Based on what you were saying I've updated the example, please tell me if something should be different:
using
System;
using
System.ComponentModel;
using
System.Windows.Forms;
using
Telerik.WinControls.UI;
public
partial
class
Form1 : Form
{
private
RadTreeView radTreeView1;
private
NodesList nodes;
private
int
view;
public
Form1()
{
InitializeComponent();
this
.Controls.Add(radTreeView1 =
new
RadTreeView());
radTreeView1.Dock = DockStyle.Fill;
var view1Button =
new
RadButton();
view1Button.Text =
"View1"
;
view1Button.Click +=
new
EventHandler(view1Button_Click);
view1Button.Dock = DockStyle.Bottom;
this
.Controls.Add(view1Button);
var view2Button =
new
RadButton();
view2Button.Text =
"View2"
;
view2Button.Click +=
new
EventHandler(view2Button_Click);
view2Button.Dock = DockStyle.Bottom;
this
.Controls.Add(view2Button);
}
void
view1Button_Click(
object
sender, EventArgs e)
{
ReloadData(1);
}
void
view2Button_Click(
object
sender, EventArgs e)
{
ReloadData(2);
}
protected
override
void
OnLoad(EventArgs e)
{
base
.OnLoad(e);
radTreeView1.LoadOnDemand =
true
;
radTreeView1.NodeExpandedChanged +=
new
RadTreeView.TreeViewEventHandler(radTreeView1_NodeExpandedChanged);
nodes =
new
NodesList();
ReloadData(1);
radTreeView1.DataSource = nodes;
radTreeView1.ParentIDMember =
"ParentId"
;
radTreeView1.ValueMember =
"Id"
;
radTreeView1.DisplayMember =
"Name"
;
}
private
void
ReloadData(
int
view)
{
radTreeView1.DataSource =
null
;
nodes.Clear();
this
.view = view;
nodes.GetFirstLevel(view);
nodes.GetSecondLevel(view);
radTreeView1.DataSource = nodes;
}
void
radTreeView1_NodeExpandedChanged(
object
sender, RadTreeViewEventArgs e)
{
if
(e.Node.Nodes.Count == 0)
{
var node = e.Node.DataBoundItem
as
Node;
nodes.GetChildNodesForNode(node.Id, view);
}
}
}
public
class
Node
{
public
int
Id
{
get
;
set
;
}
public
int
ParentId
{
get
;
set
;
}
public
string
Name
{
get
;
set
;
}
}
public
class
NodesList : BindingList<Node>
{
public
NodesList()
{
}
public
void
GetFirstLevel(
int
view)
{
for
(
int
i = 0; i < 4; i++)
{
this
.Add(
new
Node
{
Id = i + view,
Name =
"Name"
+ i + view,
ParentId = i + view
});
}
}
public
void
GetSecondLevel(
int
view)
{
for
(
int
i = 4; i < 8; i++)
{
this
.Add(
new
Node
{
Id = i + view,
Name =
"Name"
+ i + view,
ParentId = i + view - 4
});
}
}
public
void
GetChildNodesForNode(
int
id,
int
view)
{
var startIndex =
this
.Count;
for
(
int
i = startIndex; i < startIndex + 4; i++)
{
this
.Add(
new
Node
{
Id = (i + view),
Name =
"Name"
+ i + view,
ParentId = id
});
}
}
}
Hope this helps, if you have any other questions or comments, please let me know,
Best Regards,
Emanuel Varga
Telerik WinForms MVP
0
Hello,
Thank you all for writing.
Sonya, I hope that you find the solution provided by Emanuel helpful. Please let us know if you need further assistance.
Emanuel, thank you for your help.
Sincerely yours,
Stefan
the Telerik team
Thank you all for writing.
Sonya, I hope that you find the solution provided by Emanuel helpful. Please let us know if you need further assistance.
Emanuel, thank you for your help.
Sincerely yours,
Stefan
the Telerik team
See What's New in RadControls for WinForms in Q3 2010 on Wednesday, November 17, 11am Eastern Time: Register here>>
0
Sonya L
Top achievements
Rank 1
answered on 17 Nov 2010, 11:13 PM
Emanuel
Thanks for your help. I was able to get it working with the following modifications. For some reason, setting the datasource to null just caused a blank treeview. Also, without the Begin/End Update, the app would hang when I tried to change views. It seems to work now though. Thanks!
Thanks for your help. I was able to get it working with the following modifications. For some reason, setting the datasource to null just caused a blank treeview. Also, without the Begin/End Update, the app would hang when I tried to change views. It seems to work now though. Thanks!
private void ReloadData(int view)
{
//added this
radTreeView1.BeginUpdate();
//replaced this
//radTreeView1.DataSource = null;
radTreeView1.Nodes.Clear();
nodes.Clear();
this.view = view;
nodes.GetFirstLevel(view);
nodes.GetSecondLevel(view);
//removed this
//radTreeView1.DataSource = nodes;
//added this
radTreeView1.EndUpdate();
}
private
void
ReloadData(
int
view)
{
//added this
radTreeView1.BeginUpdate();
//replaced this
//radTreeView1.DataSource = null;
radTreeView1.Nodes.Clear();
nodes.Clear();
this
.view = view;
nodes.GetFirstLevel(view);
nodes.GetSecondLevel(view);
//removed this
//radTreeView1.DataSource = nodes;
//added this
radTreeView1.EndUpdate();
}
private void ReloadData(int view)
{
//added this
radTreeView1.BeginUpdate();
//replaced this
//radTreeView1.DataSource = null;
radTreeView1.Nodes.Clear();
nodes.Clear();
this.view = view;
nodes.GetFirstLevel(view);
nodes.GetSecondLevel(view);
//removed this
//radTreeView1.DataSource = nodes;
//added this
radTreeView1.EndUpdate();