Editorial Note
This article appears in the Third Party Products and Tools section. Articles in this section are for the members only and must not be used to promote or advertise products in any way, shape or form. Please report any spam or advertising.
Introduction
As a web developer I may use DevExpress controls in many of web applications .In this article I will show you an example for aspxgridview (which is a popular control used in data driven applications) and how to bind it dynamically at runtime . I will be using ASP.NET suite of controls, more specifically Web Forms
Creating the project
I will create an empty Visual Studio ASP.NET Web Application. I created also a simple database that contains a master table (Categories) and another detail table (Products) and a record in (Products) table refere to a record in (Categories) table as the following image shows.
<img height="176px" src="1117804/Products-CategoriesTables.png" width="614px" />
I created database using SQL server 2012 and the application is written for .net framework 4.5 with examples written in C# ,and the devexpress version I used is Version=15.2.4.0 .
Using the code
I created a simple DataHelper Class to retrieve data from the database i will not be focused on the practices to get data from database but the way to create and bind the data to detail template grid.
Creating DataHelper Class
The DataHelper Class contains two methods the first method (GetConnection) used to get database connection for the database MasterDetailDB on the local server.
The second method (getDataTable) used to get a datatable and it takes a query as string parameter to be executed aginst the database.
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
namespace MasterDetailTemplateRuntim.AppCode
{
public class DataHelper
{
public SqlConnection GetConnection()
{
string connStr = System.Configuration.ConfigurationManager.ConnectionStrings["MasterDetailDBConnectionString"].ConnectionString;
SqlConnection conn = new SqlConnection(connStr);
return conn;
}
public DataTable getDataTable(string query)
{
DataTable table = new DataTable("Table");
SqlCommand cmd = new SqlCommand(query, GetConnection());
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(table);
return table;
}
}
}
The getDataTable method used to bind both master and detail grid and this depends on the passed query.
Adding DetailGridTemplate Class
DetailGridTemplate Class is a class that implement ITemplate interface then it must implement instantiateIn method that detrmines which control to instantiate the template in.
using DevExpress.Web;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
namespace MasterDetailTemplateRuntim.AppCode
{
public class DetailGridTemplate: ITemplate
{
Control parent;
object masterKey;
ASPxGridView detailGrid;
public DetailGridTemplate(ASPxGridView grid)
{
this.detailGrid = grid;
}
public void InstantiateIn(Control container)
{
parent = container;
masterKey = ((GridViewDetailRowTemplateContainer)parent).KeyValue;
parent.Controls.Add(detailGrid);
}
}
}
As before, the DetailGridTemplate class has a public constructor that takes the detailgrid as a paramter to add it to the tamplate.
Creating the Master and the Detail Grids
Now we add a webform (MasterDetailPage.aspx) and inside the Page_Load event handler we create an ASPxGridView object.
using DevExpress.Web;
using MasterDetailTemplateRuntim.AppCode;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace MasterDetailTemplateRuntim
{
public partial class MasterDetailPage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
ASPxGridView MasterGrid = new ASPxGridView();
ASPxGridView dGrid = new ASPxGridView();
dGrid.BeforePerformDataSelect += dGrid_BeforePerformDataSelect;
MasterGrid.AutoGenerateColumns = true;
MasterGrid.SettingsDetail.ShowDetailRow = true;
MasterGrid.KeyFieldName = "ID";
}
}
}
As you see the above code creates the master and detail grids and register the BeforePerformDataSelect handler for the detail grid two allow binding the detail grid with a datasource at runtime.
Creating the DetailGridTemplate
At the next code segment, a DetialGridTemplate instance is created and assigned to the mastergrid detial row template in one step.Note, that the detail grid passed as a parameter to the constructor.
MasterGrid.Templates.DetailRow = new DetailGridTemplate(dGrid);
And binding the master grid datasource
DataHelper dh=new DataHelper();
MasterGrid.DataSource = dh.getDataTable("select * from categories");
MasterGrid.DataBind();
Page.Form.Controls.Add(MasterGrid);
Now for binding the detail grid according to the master record we create the handler method that handle BeforePerformDataSelect Event .
void dGrid_BeforePerformDataSelect(object sender, EventArgs e)
{
ASPxGridView grid=sender as ASPxGridView;
grid.AutoGenerateColumns = true;
DataHelper dh = new DataHelper();
grid.DataSource =dh.getDataTable("select * from products where categoryID="+ grid.GetMasterRowKeyValue().ToString());
}
As the previous code the ASPxGridView class provide a method to get the master row of the master grid 's key value (GetMasterRowKeyValue) which used to get all detail row related to the master row.
finally the MasterDetailPage.aspx.cs looks like this.
using DevExpress.Web;
using MasterDetailTemplateRuntim.AppCode;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace MasterDetailTemplateRuntim
{
public partial class MasterDetailPage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//create master grid
ASPxGridView MasterGrid = new ASPxGridView();
ASPxGridView dGrid = new ASPxGridView();
dGrid.BeforePerformDataSelect += dGrid_BeforePerformDataSelect;
MasterGrid.AutoGenerateColumns = true;
MasterGrid.SettingsDetail.ShowDetailRow = true;
MasterGrid.KeyFieldName = "ID";
//create detail grid and add it to the detail tamplate
MasterGrid.Templates.DetailRow = new DetailGridTemplate(dGrid);
DataHelper dh=new DataHelper();
MasterGrid.DataSource = dh.getDataTable("select * from categories");
MasterGrid.DataBind();
Page.Form.Controls.Add(MasterGrid);
//add the template to grid
}
void dGrid_BeforePerformDataSelect(object sender, EventArgs e)
{
ASPxGridView grid=sender as ASPxGridView;
grid.AutoGenerateColumns = true;
DataHelper dh = new DataHelper();
grid.DataSource =dh.getDataTable("select * from products where categoryID="+ grid.GetMasterRowKeyValue().ToString());
}
}
}
and MasterDetailPage.aspx does not contain any grids but all of this done programatically.
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="MasterDetailPage.aspx.cs" Inherits="MasterDetailTemplateRuntim.MasterDetailPage" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
</div>
</form>
</body>
</html>
The final result should be like this.
<img height="221px" src="1117804/final_result.png" width="284px" />
The source code
You can find the source code with database script here and please read readme file first.