Back to Devexpress

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

aspnet-3873-components-grid-view-examples-how-to-implement-master-detail-at-runtime-xpo.md

latest8.0 KB
Original Source

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

  • Nov 18, 2021
  • 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

csharp
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); }
    }

    [Association("Customer-Orders")]
    public Customer Customer;
}
vb
Imports DevExpress.Xpo

Public Class Customer
    Inherits XPObject
    Public Sub New(ByVal session As Session)
        MyBase.New(session)
    End Sub
    Private fCustomerName As String
    Public Property CustomerName() As String
        Get
            Return fCustomerName
        End Get
        Set
            SetPropertyValue(Of String)("CustomerName", fCustomerName, Value)
        End Set
    End Property

    <Association("Customer-Orders", GetType(Order)), Aggregated> _
    Public ReadOnly Property Orders() As XPCollection
        Get
            Return GetCollection("Orders")
        End Get
    End Property
End Class

Public Class Order
    Inherits XPObject
    Public Sub New(ByVal session As Session)
        MyBase.New(session)
    End Sub
    Private fProductName As String
    Public Property ProductName() As String
        Get
            Return fProductName
        End Get
        Set
            SetPropertyValue(Of String)("ProductName", fProductName, Value)
        End Set
    End Property

    Private fOrderDate As DateTime
    Public Property OrderDate() As DateTime
        Get
            Return fOrderDate
        End Get
        Set
            SetPropertyValue(Of DateTime)("OrderDate", fOrderDate, Value)
        End Set
    End Property

    <Association("Customer-Orders")> _
    Public Customer As Customer
End Class

Note

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).

csharp
void Application_Start(object sender, EventArgs e) {
    string conn = DevExpress.Xpo.DB.AccessConnectionProvider.GetConnectionString(
  Server.MapPath("~\\App_Data\\Customer.mdb"));
    DevExpress.Xpo.Metadata.XPDictionary dict = new DevExpress.Xpo.Metadata.ReflectionDictionary();
    // Initialize the XPO dictionary.
    dict.GetDataStoreSchema(typeof(Customer).Assembly);
    DevExpress.Xpo.XpoDefault.Session = null;
    DevExpress.Xpo.DB.IDataStore store = DevExpress.Xpo.XpoDefault.GetConnectionProvider(conn,
                      DevExpress.Xpo.DB.AutoCreateOption.SchemaAlreadyExists);
    DevExpress.Xpo.XpoDefault.DataLayer = new DevExpress.Xpo.ThreadSafeDataLayer(dict, store);
}
vb
Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
Dim path As String = "~\App_Data\Customer.mdb"
Dim conn = DevExpress.Xpo.DB.AccessConnectionProvider.GetConnectionString(Server.MapPath(path))
   Dim dict As DevExpress.Xpo.Metadata.XPDictionary 
   = New DevExpress.Xpo.Metadata.ReflectionDictionary()
   ' Initialize the XPO dictionary.
   dict.GetDataStoreSchema(GetType(Customer).Assembly)
   DevExpress.Xpo.XpoDefault.Session = Nothing
   Dim store = DevExpress.Xpo.XpoDefault.GetConnectionProvider(conn,_
       DevExpress.Xpo.DB.AutoCreateOption.SchemaAlreadyExists)
   DevExpress.Xpo.XpoDefault.DataLayer = New DevExpress.Xpo.ThreadSafeDataLayer(dict, store)
End Sub

Note

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

  • Detail : Orders

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

4. Create Detail ASPxGridView

csharp
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";
        detailGridView.BeforePerformDataSelect 
        += new EventHandler(detailGridView_BeforePerformDataSelect);
        container.Controls.Add(detailGridView);
    }
    void detailGridView_BeforePerformDataSelect(object sender, EventArgs e) {
        HttpContext.Current.Session["Oid"] = (sender as ASPxGridView).GetMasterRowKeyValue();
    } 
}
vb
Imports DevExpress.Web.ASPxGridView

Public Class DetailRowTemplate
    Implements ITemplate
    Private dataSource As Object = Nothing
    Public Sub New(ByVal dataSource As Object)
        Me.dataSource = dataSource
    End Sub
    Public Sub InstantiateIn(ByVal container As Control) Implements ITemplate.InstantiateIn
        Dim detailGridView As ASPxGridView = New ASPxGridView()
        detailGridView.SettingsDetail.IsDetailGrid = True
        detailGridView.DataSource = dataSource
        detailGridView.KeyFieldName = "Oid"
        AddHandler detailGridView.BeforePerformDataSelect, 
        AddressOf detailGridView_BeforePerformDataSelect
           container.Controls.Add(detailGridView)
  End Sub
  Private Sub detailGridView_BeforePerformDataSelect(ByVal sender As Object, ByVal e As EventArgs)
      HttpContext.Current.Session("Oid") = (TryCast(sender, ASPxGridView)).GetMasterRowKeyValue()
    End Sub
End Class

5. Create Master ASPxGridView

csharp
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";
    ASPxRoundPanel1.Controls.Add(gv);
    gv.DataBind();
}
vb
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
    Dim gv As ASPxGridView = New ASPxGridView()
    gv.DataSource = dsCustomers
    gv.SettingsDetail.ShowDetailRow = True
    gv.SettingsDetail.ShowDetailButtons = True
    gv.Templates.DetailRow = New DetailRowTemplate(dsOrders)
    gv.KeyFieldName = "Oid"
    ASPxRoundPanel1.Controls.Add(gv)
    gv.DataBind()
End Sub