RadGrid for ASP.NET

Self-referencing hierarchy Send comments on this topic.
Populating the control with data > Self-referencing hierarchy

Glossary Item Box

This feature is available since version 4.0.0 of Telerik RadGrid. It allows you to build multiple levels of hierarchy from a single table in the data source by specifying relations inside the same table.  You do not need to create separate tables for each child level - one table is sufficient to define the hierarchy schema.  All visual settings will be applied to the nested tables as well.
Below are steps needed to implement the self-referencing feature of the grid:

  • add the fields from the grid source which define the parent/child relations (ParentID and ID in this case) to the DataKeyNames array of the MasterTableView
  • configure these fields through the SelfReferencingSettings property of the MasterTableView. The ParentKeyName subproperty has to point to the parent item id, while KeyName references the id value for the current table level. 
  • define the root level filter for the grid hierarchy depending on your source table conventions (in this demo the root items have a parent ID of 0). This can be done through the FilterExpression property of the MasterTableView instance:
     
    RadGrid1.MasterTableView.FilterExpression = "ParentID = 0"

In addition, you can hide the header item for the tables in the hierarchy wiring the ItemCreated event of the grid if it is not needed.

  • you can also set the MaximumDepth sub-property of SelfReferencingSettings  (not used in this example) to limit the depth of the nested tables.
    This property can be set only once when the grid is initialized and can not be modified. Otherwise it will throw an exception because of the modified grid structure.

    

If you want to display the header in self-referencing grid for the master table only, add the following check inside the ItemCreated event handler:

C# Copy Code
protected void RadGrid1_ItemCreated(object sender, GridItemEventArgs e)
{
       
if (e.Item is GridHeaderItem && e.Item.OwnerTableView != RadGrid1.MasterTableView)
       {
           e.Item.Style[
"display"] = "none";
       }
}

VB.NET Copy Code
Protected Sub RadGrid1_ItemCreated(ByVal sender as Object, ByVal e as GridItemEventArgs)
        If (TypeOf e.Item Is GridHeaderItem AndAlso (Not e.Item.OwnerTableView Is RadGrid1.MasterTableView)) Then
            e.Item.Style("display") = "none"
        EndIf
End Sub


Below is a code extraction:

ASPX/ASCX Copy Code
<rad:RadGrid ID="RadGrid1" EnableAJAX="True" ShowHeader="true" runat="server" Skin="None"
                       
Width= "97%" GridLines="None" OnColumnCreated="RadGrid1_ColumnCreated" OnItemCreated="RadGrid1_ItemCreated"
                       
OnNeedDataSource= "RadGrid1_NeedDataSource">
                       
<MasterTableView HierarchyDefaultExpanded="true" HierarchyLoadMode="Client" EnableNoRecordsTemplate="false"
                           
DataKeyNames= "ID,ParentID" Width="100%">
                           
<SelfHierarchySettings ParentKeyName="ParentID" KeyName="ID" />
                       
</MasterTableView>
                       
<ClientSettings AllowExpandCollapse="true" />
</
rad:RadGrid>

 

C# Copy Code
private static DataTable GetDataTable(string query)
{
           OleDbConnection connection1 =
new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" +
           System.Web.HttpContext.Current.Server.MapPath(
"~/Grid/Data/Access/db1.mdb"));
           OleDbDataAdapter adapter1 =
new OleDbDataAdapter();
           adapter1.SelectCommand =
new OleDbCommand(query, connection1);
           DataTable table1 =
new DataTable();
           connection1. Open();
           
try
           {
               
adapter1.Fill(table1);
           }
           
finally
           {
               
connection1. Close();
           }
            
return table1;
}

protected void RadGrid1_NeedDataSource(object source, Telerik.WebControls.GridNeedDataSourceEventArgs e)
{
    RadGrid1.DataSource = GetDataTable(
"SELECT * FROM SelfReferencing");
}

protected void RadGrid1_ColumnCreated(object sender, GridColumnCreatedEventArgs e)
{
            
if (e.Column.IsBoundToFieldName("ID") || e.Column.IsBoundToFieldName("ParentID"))
           {
               e.Column.Visible = false;
           }
}

public void Page_Load(object sender, EventArgs e)
{
            
if (!IsPostBack)
           {
               RadGrid1.MasterTableView.FilterExpression =
"ParentID = 0";
           }
}

protected void RadGrid1_ItemCreated(object sender, GridItemEventArgs e)
{
            
if (e.Item is GridHeaderItem)
           {
               e.Item.Style[
"display"] = "none";
           }
}
VB.NET Copy Code
Public Function GetDataTable(ByVal query As String) As DataTable
             Dim connection1 As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & System.Web.HttpContext.Current.Server.MapPath( "~/Grid/Data/Access/db1.mdb"))
             Dim adapter1 As New OleDbDataAdapter
            adapter1.SelectCommand = New OleDbCommand(query, connection1)
             Dim table1 As New DataTable
            connection1. Open()
            Try
                adapter1.Fill(table1)
            Finally
                connection1. Close()
             End Try
             Return table1
         End Function


Private Sub RadGrid1_NeedDataSource(ByVal source As Object, ByVal e As GridNeedDataSourceEventArgs) Handles RadGrid1.NeedDataSource
            RadGrid1.DataSource = GetDataTable("SELECT * FROM SelfReferencing")
End Sub

Private Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
             If Not IsPostBack Then
                RadGrid1.MasterTableView.FilterExpression = "ParentID = 0"
             End If
End Sub

Private Sub RadGrid1_ColumnCreated(ByVal sender As Object, ByVal e As WebControls.GridColumnCreatedEventArgs) Handles RadGrid1.ColumnCreated
             If (e.Column.IsBoundToFieldName("ID") OrElse e.Column.IsBoundToFieldName("ParentID")) Then
                e.Column.Visible = False
             End If
         End Sub

         Private Sub RadGrid1_ItemCreated(ByVal sender As Object, ByVal e As WebControls.GridItemEventArgs) Handles RadGrid1.ItemCreated
             If (TypeOf e.Item Is GridHeaderItem) Then
                e.Item.Style( "display") = "none"
             End If
End Sub

 Self-referencing in Telerik RadGrid