RadGrid for ASP.NET

Hierarchical data-binding using declarative relations Send comments on this topic.
Populating the control with data > Hierarchical data-binding using declarative relations

Glossary Item Box

We would like to draw your attention to the following online examples of Telerik RadGrid concerning three level hierarchy:

http://www.telerik.com/demos/aspnet/Grid/Examples/Hierarchy/ThreeLevel/DefaultCS.aspx  (.NET 2.0)

Here is an extraction of the html code of the grid in them:

ASPX/ASCX Copy Code
<rad:radgrid id="RadGrid1" runat="server"
 
CssClass="RadGrid" Width="95%" AutoGenerateColumns="False" PageSize="3"
 
AllowSorting="True" AllowMultiRowSelection="False" AllowPaging="True"
 
GridLines="None">
   
<MasterTableView DataKeyNames="CustomerID" AllowMultiColumnSorting="True"
    
Width="100%">
     
<DetailTables>
       
<rad:GridTableView DataKeyNames="OrderID" DataMember="Orders" Width="100%"
        
Gridlines= "Horizontal" style="border-color:#d5b96a" CssClass="RadGrid2">
          
<ParentTableRelation>
            
<rad:GridRelationFields DetailKeyField="CustomerID"
             
MasterKeyField= "CustomerID" />
          
</ParentTableRelation>
            
<DetailTables>
             
<rad:GridTableView DataKeyNames="OrderID" DataMember="OrderDetails"
              
Width= "100%" Gridlines="Horizontal" style="border-color:#d5b96a"
              
CssClass= "RadGrid3">
                 
<ParentTableRelation>
                  
<rad:GridRelationFields DetailKeyField="OrderID"
                   
MasterKeyField= "OrderID" />
                 
</ParentTableRelation>
                  
<Columns>
                    
<rad:GridBoundColumn SortExpression="UnitPrice" HeaderText="Unit
                     
Price " HeaderButtonType="TextButton" DataField="UnitPrice" />
                    
<rad:GridBoundColumn SortExpression="Quantity"
                     
HeaderText= "Quantity" HeaderButtonType="TextButton"
                     
DataField= "Quantity" />
                    
<rad:GridBoundColumn SortExpression="Discount"
                     
HeaderText= "Discount" HeaderButtonType="TextButton"
                     
DataField= "Discount" />
                  
</Columns>
               
</rad:GridTableView>
            
</DetailTables>
         
<Columns>
           
<rad:GridBoundColumn SortExpression="OrderID" HeaderText="OrderID"
            
HeaderButtonType= "TextButton" DataField="OrderID" />
           
<rad:GridBoundColumn SortExpression="OrderDate" HeaderText="Date Ordered"
            
HeaderButtonType= "TextButton" DataField="OrderDate" />
           
<rad:GridBoundColumn SortExpression="EmployeeID" HeaderText="EmployeeID"
            
HeaderButtonType= "TextButton" DataField="EmployeeID" />
         
</Columns>
      
</rad:GridTableView>
    
</DetailTables>
  
<Columns>
   
<rad:GridBoundColumn SortExpression="CustomerID" HeaderText="CustomerID"
    
HeaderButtonType= "TextButton" DataField="CustomerID" />
   
<rad:GridBoundColumn SortExpression="ContactName" HeaderText="Contact Name"
    
HeaderButtonType= "TextButton" DataField="ContactName" />
   
<rad:GridBoundColumn SortExpression="CompanyName" HeaderText="Company"
    
HeaderButtonType= "TextButton" DataField="CompanyName" />
  
</Columns>
</MasterTableView>
</
rad:radgrid>



As you can see from the highlighted parts in the code, you need to define the ParentTableRelations/DataKeyNames for the MasterTableView/GridTableViews according to the database relations conventions (presented in the forthcoming screenshot):

Table Relations in Northwind database

And here are the exact conventions:

  • the primary key column name for each table in the grid source (used for master/detail table population) should be added to the DataKeyNames collection of the respective master/detail table;
  • the MasterKeyField in the GridRelationFields should match the primary key of the parent table in the corresponding relation;
  • the DetailKeyField in the GridRelationFields should match the foreign key of the child table in the corresponding relation.

There is one more detail if you use declarative binding using DataSource controls under .NET 2.0:

You should have WHERE clause in the SelectCommand of the second DataSource control which to filter the records for the child table. The WHERE clause should include the field from the ParentTableRelation definition between the master/child table. Furthermore, that same field has to be included in the SelectParameters of the second DataSource (with exactly the same Name and SessionField value):

ASPX/ASCX Copy Code
<asp:AccessDataSource ID="AccessDataSource1" DataFile="~/Grid/Data/Access/Nwind.mdb"
SelectCommand="SELECT * FROM Customers" runat="server"></asp:AccessDataSource>

<
asp:AccessDataSource ID="AccessDataSource2" DataFile="~/Grid/Data/Access/Nwind.mdb"
SelectCommand="SELECT * FROM Orders Where CustomerID = ?" runat="server">
           
<SelectParameters>
               
<asp:SessionParameter Name="CustomerID" SessionField="CustomerID" Type="string" />
           
</SelectParameters>
       
</asp:AccessDataSource>
<
asp:AccessDataSource ID="AccessDataSource3" DataFile="~/Grid/Data/Access/Nwind.mdb"
SelectCommand="SELECT * FROM [Order Details] where OrderID = ?" runat="server">
           
<SelectParameters>
               
<asp:SessionParameter Name="OrderID" SessionField="OrderID" Type="Int32" />
           
</SelectParameters>
</
asp:AccessDataSource>

An important detail is that every GridRelationField should have only one field
name for DetailKeyField and MasterKeyField. For multi-hierarchy relations you can use multiple relation fields as in the example below:

ASPX/ASCX Copy Code
<ParentTableRelation>
   
<rad:GridRelationFields DetailKeyField="ID1" MasterKeyField="ID1" />
   
<rad:GridRelationFields DetailKeyField="ID2" MasterKeyField="ID2" />
   
<rad:GridRelationFields DetailKeyField="ID3" MasterKeyField="ID3" />
</
ParentTableRelation>