How to: Extend the Application Model

To demonstrate how to extend the Application Model, this topic details how to display a Group Footer for List Views. An IsGroupFooterVisible property will be added to the to the Views | <ListView> node. When set to true for a ListView, a special Controller will enable the group footer. To specify a summary type for different columns, a GroupFooterSummaryType property will be added to the ListView | Columns | Column node. For general information on extending the Application Model, refer to the Extend and Customize the Application Model in Code help topic.

Note

Mobile applications do not support the Group Footer. However, you can implement the approach described in this topic to extend your Application Model for other purposes.

HowToExdendApplicationModel

Tip

A complete sample project is available in the DevExpress Code Examples database at http://www.devexpress.com/example=E213.

  • Implement the interfaces exposing the IsGroupFooterVisible and GroupFooterSummaryType properties.

    using DevExpress.Data;
    //...
    public interface IModelListViewExtender {
        bool IsGroupFooterVisible { get; set; }
    }
    public interface IModelColumnExtender {
        [DefaultValue(SummaryItemType.None)]
        SummaryItemType GroupFooterSummaryType { get; set; }
    }
    
  • Override the ModuleBase.ExtendModelInterfaces method of your base Module to extend the Application Model with declared interfaces.

    using DevExpress.ExpressApp.Model;
    // ...
    public sealed partial class ExtendModelModule : ModuleBase {
        // ...
        public override void ExtendModelInterfaces(ModelInterfaceExtenders extenders) {
            base.ExtendModelInterfaces(extenders);
            extenders.Add<IModelListView, IModelListViewExtender>();
            extenders.Add<IModelColumn, IModelColumnExtender>();
        }
    }
    
  • Create a WinGroupFooterViewController ViewController in the Windows Forms Module. Inherit it from the ViewController<ListView> type, since this Controller must be activated in List Views only.
  • Override the protected OnViewControlsCreated method to display the group footer, if the IsGroupFooterVisible property is set to true for the current List View. Additionally, when the Controller is activated, handle the View.ModelSaved event to save the group footer summary type for different columns into Application Model, when the current List View is closing.

    using System;
    using System.ComponentModel;
    using DevExpress.Data;
    using DevExpress.ExpressApp;
    using DevExpress.ExpressApp.Model;
    using DevExpress.ExpressApp.Win.Editors;
    using DevExpress.XtraGrid.Views.Grid;
    using DevExpress.XtraGrid.Columns;
    //...
    public class WinGroupFooterViewController : ViewController<ListView> {
        private void View_ModelSaved(object sender, EventArgs e) {
            IModelListViewExtender modelListView = View.Model as IModelListViewExtender;
            if(modelListView != null && modelListView.IsGroupFooterVisible) {
                GridListEditor gridListEditor = View.Editor as GridListEditor;
                if(gridListEditor != null) {
                    GridView gridView = gridListEditor.GridView;
                    for(int i = 0; i < gridView.GroupSummary.Count; i++) {
                        IModelColumnExtender modelColumn = View.Model.Columns[
                            gridView.GroupSummary[i].FieldName] as IModelColumnExtender;
                        if(modelColumn != null) {
                            modelColumn.GroupFooterSummaryType = gridView.GroupSummary[i].SummaryType;
                        }
                    }
                }
            }
        }
        protected override void OnViewControlsCreated() {
            base.OnViewControlsCreated();
            IModelListViewExtender modelListView = View.Model as IModelListViewExtender;
            if(modelListView != null && modelListView.IsGroupFooterVisible) {
                GridListEditor gridListEditor = View.Editor as GridListEditor;
                if(gridListEditor != null) {
                    GridView gridView = gridListEditor.GridView;
                    gridView.GroupFooterShowMode = GroupFooterShowMode.VisibleAlways;
                    foreach(IModelColumn modelColumn in View.Model.Columns) {
                        IModelColumnExtender modelColumnExtender = modelColumn as IModelColumnExtender;
                        if(modelColumnExtender != null && 
                            modelColumnExtender.GroupFooterSummaryType != SummaryItemType.None) {
                            GridColumn gridColumn = gridView.Columns[
                                modelColumn.ModelMember.MemberInfo.BindingName];
                            gridView.GroupSummary.Add(modelColumnExtender.GroupFooterSummaryType, 
                                modelColumn.Id, gridColumn);
                        }
                    }
                }
            }
        }
        protected override void OnActivated() {
            base.OnActivated();
            View.ModelSaved += View_ModelSaved;
        }
        protected override void OnDeactivated() {
            View.ModelSaved -= View_ModelSaved;
            base.OnDeactivated();
        }
    }
    
  • Create a WebGroupFooterViewController ViewController in the ASP.NET Web Module. Inherit it from the ViewController<ListView> type, since this Controller must be activated in List Views only.
  • Override the protected OnViewControlsCreated method to display the group footer, if the IsGroupFooterVisible property is set to true for the current List View. There is no need to handle the ModelSaved event since end-users cannot customize summary types for different columns in the ASP.NET UI.

    using System;
    using DevExpress.Data;
    using DevExpress.ExpressApp;
    using DevExpress.ExpressApp.Model;
    using DevExpress.ExpressApp.Web.Editors.ASPx;
    using DevExpress.Web.ASPxGridView;
    //...
    public class WebGroupFooterViewController : ViewController<ListView> {
        protected override void OnViewControlsCreated() {
            base.OnViewControlsCreated();
            IModelListViewExtender modelListView = View.Model as IModelListViewExtender;
            if(modelListView != null && modelListView.IsGroupFooterVisible) {
                ASPxGridListEditor gridListEditor = View.Editor as ASPxGridListEditor;
                if(gridListEditor != null) {
                    ASPxGridView gridView = gridListEditor.Grid;
                    gridView.Settings.ShowGroupFooter = GridViewGroupFooterMode.VisibleAlways;
                    foreach(IModelColumn modelColumn in View.Model.Columns) {
                        IModelColumnExtender modelColumnExtender = modelColumn as IModelColumnExtender;
                        if(modelColumnExtender != null && 
                            modelColumnExtender.GroupFooterSummaryType != SummaryItemType.None) {
                            string fieldName = modelColumn.ModelMember.MemberInfo.BindingName;
                            ASPxSummaryItem summaryItem = null;
                            foreach(ASPxSummaryItem currentItem in gridView.GroupSummary) {
                                if(currentItem.FieldName == fieldName) {
                                    currentItem.ShowInGroupFooterColumn = modelColumn.Caption;
                                    summaryItem = currentItem;
                                    break;
                                }
                            }
                            if(summaryItem == null) {
                                summaryItem = new ASPxSummaryItem(
                                    fieldName, modelColumnExtender.GroupFooterSummaryType);
                                summaryItem.ShowInGroupFooterColumn = modelColumn.Caption;
                                gridView.GroupSummary.Add(summaryItem);
                            }
                        }
                    }
                }
            }
        }
    }
    
  • Rebuild you solution and invoke the Model Editor for the base Module. Set a ListView node's IsGroupPanelVisible property to true to be able to group the List View's columns. Set the newly added IsGroupFooterVisible property to true. Specify summary types for the ListView node's Column nodes.
  • Run the application. Display the List View with a group panel and group the List View by a column. The footer with the specified summary types will be displayed.

See Also