This is a migrated thread and some comments may be shown as answers.

Self-referencing hierarchy that is n-levels deep

8 Answers 196 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Mike Gombar
Top achievements
Rank 1
Mike Gombar asked on 08 Dec 2009, 11:37 PM
Is it possible to create a self-referencing hierarchical Silverlight GridView that is more than 1 level deep?  For example, I want to show the following hierarchy using a single list with the parentID pointing to the id for the parent node:

Parent1
    Child1.1
    Child1.2
        Child1.2.1
        Child1.2.2
Parent2
    Child2.1
    Child2.2
etc.....

8 Answers, 1 is accepted

Sort by
0
Milan
Telerik team
answered on 10 Dec 2009, 01:50 PM
Hi Mike Gombar,

 There is no problem to do that. You just have to add another ChildTableDefinition. You can use our Self Reference sample as a reference. The sample only shows one level of hierarchy. To support more levels you should simply add another level of child TableDefinitions:

<telerik:RadGridView.ChildTableDefinitions>
    <telerik:GridViewTableDefinition>
        <telerik:GridViewTableDefinition.Relation>
            <data:TableRelation IsSelfReference="True">
                <data:TableRelation.FieldNames>
                    <data:FieldDescriptorNamePair 
                        ParentFieldDescriptorName="Name" 
                        ChildFieldDescriptorName="FriendName"/>
                </data:TableRelation.FieldNames>
            </data:TableRelation>
        </telerik:GridViewTableDefinition.Relation>
        <telerik:GridViewTableDefinition.ChildTableDefinitions>
            <telerik:GridViewTableDefinition>
                <telerik:GridViewTableDefinition.Relation>
                    <data:TableRelation IsSelfReference="True">
                        <data:TableRelation.FieldNames>
                            <data:FieldDescriptorNamePair 
                        ParentFieldDescriptorName="Name" 
                        ChildFieldDescriptorName="CoachName"/>
                        </data:TableRelation.FieldNames>
                    </data:TableRelation>
                </telerik:GridViewTableDefinition.Relation>
            </telerik:GridViewTableDefinition>
        </telerik:GridViewTableDefinition.ChildTableDefinitions>
    </telerik:GridViewTableDefinition>
</telerik:RadGridView.ChildTableDefinitions>

One you create such structure you should also handle the DataLoading event to be able to turn off the hierarchy after the 2nd level:

void clubsGrid_DataLoading(object sender, GridViewDataLoadingEventArgs e)
{
    GridViewDataControl dataControl = (GridViewDataControl)sender;
  
    if (dataControl.ParentRow != null)
    {
        // configure child grid
        dataControl.ShowGroupPanel = false;
        dataControl.AutoGenerateColumns = false;
        dataControl.CanUserFreezeColumns = false;
          
        // stop hierarchy after level 2
        if (dataControl.ParentRow.GridViewDataControl != this.clubsGrid)
        {
            dataControl.ChildTableDefinitions.Clear();
        }
          
        GridViewDataColumn column = new GridViewDataColumn();
        column.DataMemberBinding = new Binding("Name");
        dataControl.Columns.Add(column);
    }
}

Hope this helps.

Best wishes,
Milan
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Mike Gombar
Top achievements
Rank 1
answered on 14 Dec 2009, 11:10 PM
I must be missing something.  Attached is my sample project.  I expect the following hierarcy:

John Smith
    - Sally Smith
        - Emma Smith
            - Lisa Smith
    - Fred Smith
        - Fred Smith Jr.

Instead, what I am getting is:

John Smith
    - Sally Smith
    - Fred Smith
Sally Smith
    - Emma Smith
Fred Smith
    - Fred Smith Jr.
Emma Smith
    - Lisa Smith
Fred Smith Jr.
Lisa Smith

It appears I am getting all the items in the list, plus all their children (only 1 level deep).  I was hoping to see all children appear only under their parent, and I would see 3 levels deep.

I am using a single list, with an EmployeeName (displayed), EmployeeID, and ReportsTo (that references the EmployeeID).

Here is my .xaml code:
<UserControl x:Class="RadGridViewTemplateBug.MainPage" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"   
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"   
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"   
     xmlns:Controls="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.GridView"   
     xmlns:telerikData="clr-namespace:Telerik.Windows.Data;assembly=Telerik.Windows.Data"   
     xmlns:telerik="clr-namespace:Telerik.Windows.Controls.GridView;assembly=Telerik.Windows.Controls.GridView"   
     xmlns:Controls1="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls"   
    mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">  
 
    <Grid x:Name="LayoutRoot">  
        <!-- ********** ROOT RADGRIDVIEW CONTROL ********** --> 
        <Controls:RadGridView x:Name="radGridViewHierarchy"   
                              AutoGenerateColumns="False" 
                              ShowGroupPanel="False" DataLoading="radGridViewHierarchy_DataLoading">  
              
            <Controls:RadGridView.ChildTableDefinitions> 
                <Controls:GridViewTableDefinition> 
                    <Controls:GridViewTableDefinition.Relation> 
                        <telerikData:TableRelation IsSelfReference="True" > 
                            <telerikData:TableRelation.FieldNames> 
                                <telerikData:FieldDescriptorNamePair ParentFieldDescriptorName="EmployeeID" ChildFieldDescriptorName="ReportsTo" /> 
                            </telerikData:TableRelation.FieldNames> 
                        </telerikData:TableRelation> 
                    </Controls:GridViewTableDefinition.Relation> 
                    <Controls:GridViewTableDefinition.ChildTableDefinitions> 
                        <Controls:GridViewTableDefinition> 
                            <Controls:GridViewTableDefinition.Relation> 
                                <telerikData:TableRelation IsSelfReference="True" > 
                                    <telerikData:TableRelation.FieldNames> 
                                        <telerikData:FieldDescriptorNamePair ParentFieldDescriptorName="EmployeeID" ChildFieldDescriptorName="ReportsTo" /> 
                                    </telerikData:TableRelation.FieldNames> 
                                </telerikData:TableRelation> 
                            </Controls:GridViewTableDefinition.Relation> 
                        </Controls:GridViewTableDefinition> 
                    </Controls:GridViewTableDefinition.ChildTableDefinitions> 
                </Controls:GridViewTableDefinition> 
            </Controls:RadGridView.ChildTableDefinitions> 
              
             <Controls:RadGridView.Columns> 
                <Controls:GridViewDataColumn Width="Auto" Header="Employee Name">  
                    <Controls:GridViewColumn.CellTemplate> 
                        <DataTemplate> 
                            <TextBlock Text="{Binding EmployeeName}" /> 
                        </DataTemplate> 
                    </Controls:GridViewColumn.CellTemplate> 
                </Controls:GridViewDataColumn> 
            </Controls:RadGridView.Columns> 
        </Controls:RadGridView> 
    </Grid> 
</UserControl> 
 

And the associated .cs code:
using System.IO;  
using System.Net;  
using System.Windows.Data;  
using System.Windows.Controls;  
using System.Collections.Generic;  
using Telerik.Windows.Controls;  
using Telerik.Windows.Controls.GridView;  
using Telerik.Windows.Data;  
using Telerik.Windows;  
 
namespace RadGridViewTemplateBug {  
    public partial class MainPage : UserControl {  
        public MainPage() {  
            InitializeComponent();  
 
            var employeeList = new List<Employee>();  
 
            var emp = new Employee();  
            emp.EmployeeName = "John Smith";  
            emp.EmployeeID = "js";  
            emp.ReportsTo = "";  
            employeeList.Add(emp);  
 
            emp = new Employee();  
            emp.EmployeeName = "Sally Smith";  
            emp.EmployeeID = "ss";  
            emp.ReportsTo = "js";  
            employeeList.Add(emp);  
 
            emp = new Employee();  
            emp.EmployeeName = "Fred Smith";  
            emp.EmployeeID = "fs";  
            emp.ReportsTo = "js";  
            employeeList.Add(emp);  
 
            emp = new Employee();  
            emp.EmployeeName = "Emma Smith";  
            emp.EmployeeID = "es";  
            emp.ReportsTo = "ss";  
            employeeList.Add(emp);  
 
            emp = new Employee();  
            emp.EmployeeName = "Fred Smith Jr";  
            emp.EmployeeID = "fsj";  
            emp.ReportsTo = "fs";  
            employeeList.Add(emp);  
 
            emp = new Employee();  
            emp.EmployeeName = "Lisa Smith";  
            emp.EmployeeID = "ls";  
            emp.ReportsTo = "es";  
            employeeList.Add(emp);  
 
          radGridViewHierarchy.ItemsSource = employeeList;  
        }  
 
        private void radGridViewHierarchy_DataLoading(object sender, Telerik.Windows.Controls.GridView.GridViewDataLoadingEventArgs e)  
        {  
            GridViewDataControl dataControl = (GridViewDataControl)sender;  
 
            if (radGridViewHierarchy.ParentRow != null)  
            {  
                // configure child grid   
                radGridViewHierarchy.ShowGroupPanel = false;  
                radGridViewHierarchy.AutoGenerateColumns = false;  
                radGridViewHierarchy.CanUserFreezeColumns = false;  
 
                // stop hierarchy after level 2   
                if (radGridViewHierarchy.ParentRow.GridViewDataControl != this.radGridViewHierarchy )  
                {  
                    radGridViewHierarchy.ChildTableDefinitions.Clear();  
                }  
 
                GridViewDataColumn column = new GridViewDataColumn();  
                column.DataMemberBinding = new Binding("EmployeeName");  
                //radGridViewHierarchy.Columns.Add(column);  
            }   
        }  
    }  
 
    public class Employee {  
        public string EmployeeName { get; set; }  
        public string EmployeeID { get; set; }  
        public string ReportsTo { get; set; }  
    }  
 
}  
 

0
Milan
Telerik team
answered on 15 Dec 2009, 11:06 AM
Hi Mike Gombar,

 

Well, seeing all data items is actually the expected behavior since you are passing all items to the grid.

If you would like to have this structure:

John Smith
- Sally Smith
- Emma Smith
- Lisa Smith
- Fred Smith
- Fred Smith Jr.

you should restructure your data in such a way that only John Smith is the only item in the data source.


Sincerely yours,
Milan
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Michael Gombar
Top achievements
Rank 1
answered on 05 Jan 2010, 11:26 PM
I have restructured my data, and included the XAML code  for the ChildTableDefinitions as follows:

                    <telerikGridView:RadGridView.ChildTableDefinitions> 
                        <telerikGridView:GridViewTableDefinition> 
                            <telerikGridView:GridViewTableDefinition.Relation> 
                                <telerikData:PropertyRelation IsSelfReference="True" ParentPropertyName="children"/> 
                            </telerikGridView:GridViewTableDefinition.Relation> 
                         
                            <telerikGridView:GridViewTableDefinition.ChildTableDefinitions> 
                                <telerikGridView:GridViewTableDefinition> 
                                    <telerikGridView:GridViewTableDefinition.Relation> 
                                        <telerikData:PropertyRelation IsSelfReference="True" ParentPropertyName="children"/> 
                                    </telerikGridView:GridViewTableDefinition.Relation> 
                                </telerikGridView:GridViewTableDefinition> 
                            </telerikGridView:GridViewTableDefinition.ChildTableDefinitions> 
                        </telerikGridView:GridViewTableDefinition> 
                    </telerikGridView:RadGridView.ChildTableDefinitions> 

I am also setting row.IsExpandable = false if there are no children.  This is done using the RowLoaded event on the RadGridView.  But, this event is not firing for the new child rows.

How do I register the RowLoaded event handler for the Child Grid elements?

Thanks.
0
Michael Gombar
Top achievements
Rank 1
answered on 08 Jan 2010, 08:30 PM
Has anyone been able to implement the expand/collapse feature of RadGridView on child GridViews?

Thanks in advance.
0
Milan
Telerik team
answered on 11 Jan 2010, 03:24 PM
Hi Michael Gombar,

You can use the DataLoading event to access each child grid and subscribe to its RowLoaded event:

public MainPage()
{
    InitializeComponent();
      
    this.clubsGrid.ItemsSource = Club.GetPlayers();
    this.clubsGrid.DataLoading += new System.EventHandler<GridViewDataLoadingEventArgs>(clubsGrid_DataLoading);
}
  
void clubsGrid_DataLoading(object sender, GridViewDataLoadingEventArgs e)
{
    var dataControl = sender as GridViewDataControl;
  
    dataControl.RowLoaded += new System.EventHandler<RowLoadedEventArgs>(dataControl_RowLoaded);
}
  
void dataControl_RowLoaded(object sender, RowLoadedEventArgs e)
{
      
}

Hope this helps.


Kind regards,
Milan
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Siqi
Top achievements
Rank 1
answered on 22 Jun 2015, 05:55 PM

Hi Milan,

  I want to do the same thing as Mike Gombar, and I use the same method as Mike, but I get the same issue(

John Smith
    - Sally Smith
    - Fred Smith
Sally Smith
    - Emma Smith
Fred Smith
    - Fred Smith Jr.
Emma Smith
    - Lisa Smith
Fred Smith Jr.
Lisa Smith

 you said "we could justrestructure the data in such a way that only John Smith is the only item in the data source". But I don't understand how to do this. If I keep only John Smith in the list, it doesn't show the other "Employee".

 

 

0
Dimitrina
Telerik team
answered on 25 Jun 2015, 09:07 AM
Hello Siqi,

Thank you so much for sharing the solution with the community in the other forum thread you opened.

Regards,
Dimitrina
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Tags
GridView
Asked by
Mike Gombar
Top achievements
Rank 1
Answers by
Milan
Telerik team
Mike Gombar
Top achievements
Rank 1
Michael Gombar
Top achievements
Rank 1
Siqi
Top achievements
Rank 1
Dimitrina
Telerik team
Share this question
or