View previous topic :: View next topic |
Author |
Message |
thnk2wn
Joined: 22 Apr 2008 Posts: 31
|
Posted: Wed Apr 23, 2008 1:51 am Post subject: Child nodes duplicated at root level |
|
|
I have a self-referencing permissions table that currently has a root Security permission with child nodes of Users and Groups, each with their own child permissions. The first root node of the control shows the entire tree correctly. However the child nodes are also duplicated at the root level, as in the below image.
My datasource looks correct but perhaps I have incorrect binding settings. I believe all I am setting is below.
I did just start using the control but it seems rather straightforward and I believe it matches one of the samples and what I read in the help.
The problem is really the same as mentioned in this UltraTree KB: http://devcenter.infragistics.com/Support/KnowledgeBaseArticle.aspx?ArticleID=10084. I much prefer the true databinding support in your VirtualTree (great control) but a similar workaround like below does not work as it did for the UltraTree.
Code: |
void Tree_GetCellData(object sender, GetCellDataEventArgs e)
{
/*
SecActivityEntity permission = e.Row.Item as SecActivityEntity;
if (null != permission)
{
if (e.Row.Level == 0 && (null != permission.SecActivity))
{
//e.Row.Visible = false; // readonly
}
}
*/
}
|
Am I missing something? Suggestions? Thanks... |
|
Back to top |
|
|
Infralution
Joined: 28 Feb 2005 Posts: 5027
|
Posted: Wed Apr 23, 2008 6:17 am Post subject: |
|
|
Are you binding to data from a DataSet or objects from somewhere else?
If you are binding to a DataSet you should use the specialized DataViewRowBinding and DataRowRowBinding bindings rather than the more general ObjectRowBinding which you are currently using. If you set the DataSource at design time to a DataTable then Virtual Tree should automatically generate these bindings for you.
When binding to a self-referencing DataTable you can prevent all the rows in the table being shown at the top level by creating a DataView for the table and setting the RowFilter to select only the root row "eg ParentNodeID = 0". Then set this DataView as the DataSource for Virtual Tree. You can either do this in the form designer or programmatically in your constructor following the call to InitializeComponent() eg
Code: | DataView dataView = new DataView(_dataSet.Nodes, "ParentNodeID = 0", "", DataViewRowState.Unchanged);
_virtualTree.DataSource = dataView; |
If your data is not from a DataSet then the solution is similar - you need to set the DataSource to the root object (ie the Security object) - rather than the collection of all objects. _________________ Infralution Support |
|
Back to top |
|
|
thnk2wn
Joined: 22 Apr 2008 Posts: 31
|
Posted: Wed Apr 23, 2008 4:54 pm Post subject: |
|
|
We are binding to custom objects, using LLBLGEN's framework (http://www.llblgen.com/defaultgeneric.aspx).
I cannot bind to the root object as you suggest because there can be multiple roots. In my current test scenario there may be only one (Security) but it is perfectly valid to have say a root permission "Editor Forms" and another root node "Reports", each with their own children. So really I need to bind to the entire collection.
So where does this leave us? |
|
Back to top |
|
|
Infralution
Joined: 28 Feb 2005 Posts: 5027
|
Posted: Wed Apr 23, 2008 10:39 pm Post subject: |
|
|
Virtual Tree will display whatever you provide it. If you need to display multiple root nodes then you can put the root nodes in a collection (eg a List) and set the list as the DataSource. Ensure that VirtualTree.ShowRootRow is false in this case so that you don't get a node for the list object) _________________ Infralution Support |
|
Back to top |
|
|
thnk2wn
Joined: 22 Apr 2008 Posts: 31
|
Posted: Thu Apr 24, 2008 12:55 am Post subject: |
|
|
The root nodes are in a list, along with all the children. The entire tree is comprised of one self-referencing entity (permissions and their parent, if any). Binding to the collection goes back to the original problem of the child nodes showing up at the root level as well. I was just stating that I could not switch over to bind to a single root entity as suggested to fix the problem, since their can be multiple roots. So either way we do not have a workable solution since we are not using DataSets.
I know LLBLGEN does have some View classes and maybe I can do a filter solution similar to System.Data.DataView. I do not suppose you guys have any samples of databinding using the LLBLGEN framework?
I know the Infralution tree is virtual and that it would be better done at the datasource level, but the ability to hide rows / nodes would be a handy feature. Even if you have to set a mode on the control that effectively turns off the virtual mode, or maybe it stays virtual but it may be a tad slower with having to account for rows that may have manually been hidden. |
|
Back to top |
|
|
thnk2wn
Joined: 22 Apr 2008 Posts: 31
|
Posted: Thu Apr 24, 2008 12:56 am Post subject: |
|
|
The root nodes are in a list, along with all the children. The entire tree is comprised of one self-referencing entity (permissions and their parent, if any). Binding to the collection goes back to the original problem of the child nodes showing up at the root level as well. I was just stating that I could not switch over to bind to a single root entity as suggested to fix the problem, since their can be multiple roots. So either way we do not have a workable solution since we are not using DataSets.
I know LLBLGEN does have some View classes and maybe I can do a filter solution similar to System.Data.DataView. I do not suppose you guys have any samples of databinding using the LLBLGEN framework?
I know the Infralution tree is virtual and that it would be better done at the datasource level, but the ability to hide rows / nodes would be a handy feature. Even if you have to set a mode on the control that effectively turns off the virtual mode, or maybe it stays virtual but it may be a tad slower with having to account for rows that may have manually been hidden. |
|
Back to top |
|
|
Infralution
Joined: 28 Feb 2005 Posts: 5027
|
Posted: Thu Apr 24, 2008 2:01 am Post subject: |
|
|
Quote: | The root nodes are in a list, along with all the children. The entire tree is comprised of one self-referencing entity (permissions and their parent, if any). Binding to the collection goes back to the original problem of the child nodes showing up at the root level as well. |
I wasn't suggesting that you bind to the collection containing all the nodes (including children). Rather that you create a new (eg List) collection and the nodes you want to be shown as root nodes to that collection. Then set this collection as the DataSource.
Quote: | I do not suppose you guys have any samples of databinding using the LLBLGEN framework? |
No - Sorry. But if you post your experiences that may help others.
Quote: | I know the Infralution tree is virtual and that it would be better done at the datasource level, but the ability to hide rows / nodes would be a handy feature. Even if you have to set a mode on the control that effectively turns off the virtual mode, or maybe it stays virtual but it may be a tad slower with having to account for rows that may have manually been hidden. |
To support hiding rows would require VirtualTree iterate through the entire bound collection in order to determine how many rows should be visible and thus the scrollbar parameters. If you want to support hiding rows it is easy enough to do this yourself. You handle the GetChildren event and create a new collection which only includes those children which should be visible. _________________ Infralution Support |
|
Back to top |
|
|
thnk2wn
Joined: 22 Apr 2008 Posts: 31
|
Posted: Thu Apr 24, 2008 2:26 am Post subject: Filter Solution |
|
|
Thanks for the replies.
I was able to get the desired behavior w/LGEN using the below. Seems to work so far.
Code: |
IPredicateExpression filter = new PredicateExpression();
filter.Add(SecActivityFields.ParentActivity == System.DBNull.Value);
EntityView2<SecActivityEntity> dataView = new EntityView2<SecActivityEntity>(data, filter);
Tree.DataSource = dataView;
|
|
|
Back to top |
|
|
|