Skip to main content

How to: Implement Master-Detail at Runtime (XPO)

  • 4 minutes to read

This example shows how to create ASPxGridView controls at runtime to display master-detail data.


  1. Define Persistent Classes
  2. Connect to a Database Server
  3. Retrieve Data From the Database
  4. Create Detail ASPxGridView
  5. Create Master ASPxGridView

1. Define Persistent Classes

using DevExpress.Xpo;

public class Customer : XPObject {
    public Customer(Session session) : base(session) { }
    string fCustomerName;
    public string CustomerName {
        get { return fCustomerName; }
        set { SetPropertyValue<string>("CustomerName", ref fCustomerName, value); }

    [Association("Customer-Orders", typeof(Order)), Aggregated]
    public XPCollection Orders { get { return GetCollection("Orders"); } }

public class Order : XPObject {
    public Order(Session session) : base(session) { }
    string fProductName;
    public string ProductName {
        get { return fProductName; }
        set { SetPropertyValue<string>("ProductName", ref fProductName, value); }

    DateTime fOrderDate;
    public DateTime OrderDate {
        get { return fOrderDate; }
        set { SetPropertyValue<DateTime>("OrderDate", ref fOrderDate, value); }

    public Customer Customer;


See the following topic for detailed information on how to create XPObjects: Relationships Between Objects.

2. Connect to a Database Server

Create an IDataLayer object to connect XPO to a database server. The code that creates the data layer must be placed inside the Application_Start event handler in the Global.asax module of your website. See the following topic for more information: Connecting XPO to a Database Server (ASP.NET).

void Application_Start(object sender, EventArgs e) {
    string conn = DevExpress.Xpo.DB.AccessConnectionProvider.GetConnectionString(
    DevExpress.Xpo.Metadata.XPDictionary dict = new DevExpress.Xpo.Metadata.ReflectionDictionary();
    // Initialize the XPO dictionary.
    DevExpress.Xpo.XpoDefault.Session = null;
    DevExpress.Xpo.DB.IDataStore store = DevExpress.Xpo.XpoDefault.GetConnectionProvider(conn,
    DevExpress.Xpo.XpoDefault.DataLayer = new DevExpress.Xpo.ThreadSafeDataLayer(dict, store);


See the following topic for details on how to connect to a database server: Connecting XPO to a Database Server (ASP.NET).

3. Retrieve Data From the Database

Use the XpoDataSource components to retrieve data from the database.

  • Master: Customers


    Set its TypeName property to Customer.

  • Detail: Orders


    Set its TypeName to Order.

    Use the Criteria property to specify the filter condition. Set this property to ‘[Customer.Oid] = ?’.

    Invoke the Parameter Collection Editor, and add a criteria parameter. This parameter gets its value at runtime from the “Oid” Session field.


  • Handle the page’s Init event to bind XpoDataSource components to a database.

    using DevExpress.Xpo;
    Session session;
    protected void Page_Init(object sender, EventArgs e) {
        session = new Session();
        dsCustomers.Session = session;
        dsOrders.Session = session;

4. Create Detail ASPxGridView

public class DetailRowTemplate : ITemplate {
    object dataSource = null;
    public DetailRowTemplate(object dataSource) {
        this.dataSource = dataSource;
    public void InstantiateIn(Control container) {
        ASPxGridView detailGridView = new ASPxGridView();
        detailGridView.SettingsDetail.IsDetailGrid = true;
        detailGridView.DataSource = dataSource;
        detailGridView.KeyFieldName = "Oid";
        += new EventHandler(detailGridView_BeforePerformDataSelect);
    void detailGridView_BeforePerformDataSelect(object sender, EventArgs e) {
        HttpContext.Current.Session["Oid"] = (sender as ASPxGridView).GetMasterRowKeyValue();

5. Create Master ASPxGridView

protected void Page_Load(object sender, EventArgs e) {
    ASPxGridView gv = new ASPxGridView();
    gv.DataSource = dsCustomers;
    gv.SettingsDetail.ShowDetailRow = true;
    gv.SettingsDetail.ShowDetailButtons = true;
    gv.Templates.DetailRow = new DetailRowTemplate(dsOrders);
    gv.KeyFieldName = "Oid";