Skip to main content

DevExpress v24.1 Update — Your Feedback Matters

Our What's New in v24.1 webpage includes product-specific surveys. Your response to our survey questions will help us measure product satisfaction for features released in this major update and help us refine our plans for our next major release.

Take the survey Not interested

Custom UI Logic Using Client-Side Events and Server-Side Callbacks (ASP.NET Web Forms)

  • 5 minutes to read

This topic describes how to raise XAF callbacks from the client-side events and process these events on the server. Use this approach if you cannot use a default control callback to implement a behavior and need to refresh the page or show a pop-up window.

Follow the steps below to show a Pivot Grid cell’s related objects list when a user clicks this cell. You can use a similar approach with any other web control.

  • In the ASP.NET Web Forms module project, create a ViewController and implement the CallbackManager property which returns the XafCallbackManager object.

    using DevExpress.ExpressApp;
    using DevExpress.ExpressApp.Web;
    using DevExpress.ExpressApp.Web.Templates;
    // ...
    public class PivotDrillDownController : ViewController<ListView> {
        protected XafCallbackManager CallbackManager {
            get { return ((ICallbackManagerHolder)WebWindow.CurrentRequestPage).CallbackManager; }
        }
    }
    
  • Override the OnViewControlsCreated method, access the ASPxPivotGrid control and register a new script for the client-side ASPxClientPivotGrid.CellClick event. To create the script, use the XafCallbackManager.GetScript method with the following parameters:

    Parameter Description
    handlerId The registered handler’s identifier. The value must be unique for each handler instance. You can use the Guid.NewGuid or Object.GetHashCode methods to create a unique handlerId value.
    parameters A string value passed from the client side when the XAF callback is called. In this example, the cell’s ColumnIndex and RowIndex values are passed. You can pass an empty string if parameters are not required.
    using DevExpress.ExpressApp;
    using DevExpress.ExpressApp.PivotGrid.Web;
    using DevExpress.ExpressApp.Web;
    using DevExpress.ExpressApp.Web.Templates;
    using DevExpress.ExpressApp.Web.Utils;
    using DevExpress.Web.ASPxPivotGrid;
    // ...
    public class PivotDrillDownController : ViewController<ListView> {
        // ...
        private readonly string handlerId;
        protected override void OnViewControlsCreated() {
            base.OnViewControlsCreated();
            ASPxPivotGridListEditor pivotGridListEditor = View.Editor as ASPxPivotGridListEditor;
            if(pivotGridListEditor != null) {
                ASPxPivotGrid pivotGrid = pivotGridListEditor.PivotGridControl;
                string script = CallbackManager.GetScript(handlerId, "e.ColumnIndex + ';' + e.RowIndex");
                ClientSideEventsHelper.AssignClientHandlerSafe(pivotGrid, "CellClick", "function(s, e) {" + script + "}", "PivotDrillDownController");
            }
        }
        public PivotDrillDownController() {
            handlerId = "PivotDrillDownHandler" + GetHashCode();
        }
    }
    

    Note

    Use the ClientSideEventsHelper.AssignClientHandlerSafe method to register the client-side event handler script and avoid replacing the existing scripts that handle the same client-side event.

  • Implement the IXafCallbackHandler interface in your Controller. To register an XAF callback handler, override the OnViewControlCreated method and call the XafCallbackManager.RegisterHandler method. The first parameter is the handlerId value created earlier. The second parameter is an IXafCallbackHandler object (the current Controller instance).

    using DevExpress.ExpressApp;
    using DevExpress.ExpressApp.Web.Templates;
    // ...
    public class PivotDrillDownController : ViewController<ListView>, IXafCallbackHandler {
        // ...
        private readonly string handlerId;
        protected override void OnViewControlsCreated() {
            base.OnViewControlsCreated();
            CallbackManager.RegisterHandler(handlerId, this);
            // ...
        }
        void IXafCallbackHandler.ProcessAction(string parameter) { 
        }
        // ...
    }
    

    Note

    • Register an XAF callback handler in the OnViewControlsCreated method, because this method is called before processing each page callback.
    • If the WebApplication.OptimizationSettings.AllowFastProcessListViewRecordActions option is enabled, the OnViewControlsCreated method is not called when you customize the ListViewShowObject and Edit Actions. Refer to the Faster rendering and other performance optimizations for popular Web UI scenarios in XAF KB article for details on how to disable this option.
  • Add the code that the server executes when receiving the XAF callback to the ProcessAction method. For example, obtain the clicked cell’s column and row indexes from the passed parameters, retrieve the records that are used to calculate this cell summary, and display these records in the List View.

    using System;
    using System.Collections;
    using System.Linq;
    using DevExpress.Data.Filtering;
    using DevExpress.ExpressApp;
    using DevExpress.ExpressApp.PivotGrid.Web;
    using DevExpress.ExpressApp.Web.Templates;
    using DevExpress.XtraPivotGrid;
    // ...
    void IXafCallbackHandler.ProcessAction(string parameter) {
        string[] indices = parameter.Split(';');
        int columnIndex = Int32.Parse(indices[0]);
        int rowIndex = Int32.Parse(indices[1]);
        PivotDrillDownDataSource drillDown = ((ASPxPivotGridListEditor)View.Editor).PivotGridControl.CreateDrillDownDataSource(columnIndex, rowIndex);
        string name = View.ObjectTypeInfo.KeyMember.Name;
        IList keysToShow = drillDown.Cast<PivotDrillDownDataRow>().Where(row => row[name] != null).Select(row => row[name]).ToList();            
        if (keysToShow.Count > 0) {
            Type targetType = View.ObjectTypeInfo.Type;
            string viewId = Application.GetListViewId(targetType);
            CollectionSourceBase collectionSource = Application.CreateCollectionSource(Application.CreateObjectSpace(targetType), targetType, viewId);
            collectionSource.Criteria["SelectedObjects"] = new InOperator(ObjectSpace.GetKeyPropertyName(targetType), keysToShow);
            ListView listView = Application.CreateListView(viewId, collectionSource, false);
            Application.ShowViewStrategy.ShowViewInPopupWindow(listView);
        }
    }