This example demonstrates how to use the ASPxGridView to edit an in-memory data set with a master-detail relationship.
Implementation Details
The example application stores data in a DataSet object created at runtime. The DataSet
object contains master and detail data tables.
To implement the CRUD operations required to edit the grid's data, handle the following events:
Files to Look At
- Default.aspx (VB: Default.aspx)
- Default.aspx.cs (VB: Default.aspx.vb)
Documentation
- Edit Data
- Troubleshooting: Why the 'Specified method is not supported' and 'Updating is not supported by data source 'X' unless UpdateCommand is specified' errors occur
More Examples
- Grid View for ASP.NET Web Forms - Prevent the cell edit action on the client in batch edit mode
- Grid View for ASP.NET Web Forms - A simple batch editing implementation
- Grid View for ASP.NET Web Forms - How to edit a DataTable stored in ViewState at runtime
Example Code
ASPx<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApp.Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<dx:ASPxGridView ID="MasterGridView" runat="server" AutoGenerateColumns="False" SettingsPager-PageSize="3"
KeyFieldName="ID" OnRowUpdating="MasterGridView_RowUpdating" Width="588px" OnRowDeleting="MasterGridView_RowDeleting" OnRowInserting="MasterGridView_RowInserting">
<Columns>
<dx:GridViewCommandColumn ShowEditButton="True" ShowDeleteButton="True" ShowNewButton="True" />
<dx:GridViewDataTextColumn FieldName="ID" ReadOnly="True" />
<dx:GridViewDataTextColumn FieldName="Data" />
</Columns>
<SettingsDetail ShowDetailRow="True" />
<Templates>
<DetailRow>
<dx:ASPxGridView ID="DetailGridView" runat="server" AutoGenerateColumns="False" SettingsPager-PageSize="4"
KeyFieldName="ID" OnBeforePerformDataSelect="DetailGridView_BeforePerformDataSelect"
OnRowUpdating="MasterGridView_RowUpdating" Width="100%">
<Columns>
<dx:GridViewCommandColumn ShowEditButton="True" />
<dx:GridViewDataTextColumn FieldName="ID" ReadOnly="True" />
<dx:GridViewDataTextColumn FieldName="MasterID" ReadOnly="True" />
<dx:GridViewDataTextColumn FieldName="Data" />
</Columns>
</dx:ASPxGridView>
</DetailRow>
</Templates>
</dx:ASPxGridView>
</div>
</form>
</body>
</html>
C#using DevExpress.Web;
using System;
using System.Collections;
using System.Data;
using System.Web.UI;
namespace WebApp {
public partial class Default : System.Web.UI.Page {
DataSet ds = null;
protected void Page_Init(object sender, EventArgs e) {
if (!IsPostBack || (Session["DataSet"] == null)) {
ds = new DataSet();
DataTable masterTable = new DataTable();
masterTable.Columns.Add("ID", typeof(int));
masterTable.Columns.Add("Data", typeof(string));
masterTable.PrimaryKey = new DataColumn[] { masterTable.Columns["ID"] };
DataTable detailTable = new DataTable();
detailTable.Columns.Add("ID", typeof(int));
detailTable.Columns.Add("MasterID", typeof(int));
detailTable.Columns.Add("Data", typeof(string));
detailTable.PrimaryKey = new DataColumn[] { detailTable.Columns["ID"] };
int index = 0;
for (int i = 0; i < 20; i++) {
masterTable.Rows.Add(new object[] { i, "Master Row " + i });
for (int j = 0; j < 5; j++)
detailTable.Rows.Add(new object[] { index++, i, "Detail Row " + j });
}
ds.Tables.AddRange(new DataTable[] { masterTable, detailTable });
Session["DataSet"] = ds;
}
else
ds = (DataSet)Session["DataSet"];
MasterGridView.DataSource = ds.Tables[0];
MasterGridView.DataBind();
}
protected void DetailGridView_BeforePerformDataSelect(object sender, EventArgs e) {
ds = (DataSet)Session["DataSet"];
DataTable detailTable = ds.Tables[1];
DataView dv = new DataView(detailTable);
ASPxGridView detailGridView = (ASPxGridView)sender;
dv.RowFilter = "MasterID = " + detailGridView.GetMasterRowKeyValue();
detailGridView.DataSource = dv;
}
protected void MasterGridView_RowUpdating(object sender, DevExpress.Web.Data.ASPxDataUpdatingEventArgs e) {
ds = (DataSet)Session["DataSet"];
ASPxGridView gridView = (ASPxGridView)sender;
DataTable dataTable = gridView.GetMasterRowKeyValue() != null ? ds.Tables[1] : ds.Tables[0];
DataRow row = dataTable.Rows.Find(e.Keys[0]);
IDictionaryEnumerator enumerator = e.NewValues.GetEnumerator();
enumerator.Reset();
while (enumerator.MoveNext())
row[enumerator.Key.ToString()] = enumerator.Value;
gridView.CancelEdit();
e.Cancel = true;
}
protected void MasterGridView_RowInserting(object sender, DevExpress.Web.Data.ASPxDataInsertingEventArgs e) {
ds = (DataSet)Session["DataSet"];
ASPxGridView gridView = (ASPxGridView)sender;
DataTable dataTable = gridView.GetMasterRowKeyValue() != null ? ds.Tables[1] : ds.Tables[0];
DataRow row = dataTable.NewRow();
e.NewValues["ID"] = GetNewId();
IDictionaryEnumerator enumerator = e.NewValues.GetEnumerator();
enumerator.Reset();
while (enumerator.MoveNext())
if (enumerator.Key.ToString() != "Count")
row[enumerator.Key.ToString()] = enumerator.Value;
gridView.CancelEdit();
e.Cancel = true;
dataTable.Rows.Add(row);
}
protected void MasterGridView_RowDeleting(object sender, DevExpress.Web.Data.ASPxDataDeletingEventArgs e) {
int i = MasterGridView.FindVisibleIndexByKeyValue(e.Keys[MasterGridView.KeyFieldName]);
Control c = MasterGridView.FindDetailRowTemplateControl(i, "ASPxGridView2");
e.Cancel = true;
ds = (DataSet)Session["DataSet"];
ds.Tables[0].Rows.Remove(ds.Tables[0].Rows.Find(e.Keys[MasterGridView.KeyFieldName]));
}
private int GetNewId() {
ds = (DataSet)Session["DataSet"];
DataTable table = ds.Tables[0];
if (table.Rows.Count == 0) return 0;
int max = Convert.ToInt32(table.Rows[0]["ID"]);
for (int i = 1; i < table.Rows.Count; i++) {
if (Convert.ToInt32(table.Rows[i]["ID"]) > max)
max = Convert.ToInt32(table.Rows[i]["ID"]);
}
return max + 1;
}
}
}