Responsive Mode

The Grid View control provides support for the responsive layout mode, which forces the Grid View to hide columns that do not fit the current screen resolution. Every grid row displays an ellipsis button if at least one column is hidden. Clicking this button expands an adaptive detail row displaying the hidden data.

Call the AdaptivityMode method (available through SettingsAdaptivity) with the HideDataCells argument to enable the responsive mode.

Scroll to the Grid View displayed below and toggle between screen orientations using the corresponding buttons on the right to see the responsive behavior in action.

@model IEnumerable<EditableProduct>
@(Html.DevExpress()
    .BootstrapGridView<EditableProduct>("gridResponsiveLayout")
    .SettingsAdaptivity(settings => settings
        .AdaptivityMode(GridViewAdaptivityMode.HideDataCells)
        .AllowOnlyOneAdaptiveDetailExpanded(true))
    .KeyFieldName(m => m.ProductID)
    .Columns(columns => {
        columns
            .AddCommandColumn()
            .ShowEditButton(true)
            .Width(50)
            .AdaptivePriority(1);
        columns.Add(m => m.ProductName);
        columns
            .Add(m => m.QuantityPerUnit)
            .AdaptivePriority(1);
        columns
            .AddSpinEditColumn(m => m.UnitPrice)
            .PropertiesSpinEdit(p => p
                    .DisplayFormatString("c")
                    .DisplayFormatInEditMode(true)
                    .MinValue(0)
                    .MaxValue(60000)
                )
            .Width(100);
        columns
            .AddSpinEditColumn(m => m.UnitsInStock)
            .PropertiesSpinEdit(p => p
                .MinValue(0)
                .MaxValue(10000))
            .Width(110);
        columns
            .AddCheckColumn(m => m.Discontinued)
            .Width(100)
            .AdaptivePriority(2);
    })
    .TotalSummary(summary =>
        summary
            .Add()
            .FieldName("ProductName")
            .SummaryType(SummaryItemType.Count))
    .Routes(routes => routes
        .MapRoute(r => r
            .Action("ResponsiveLayoutPartial")
            .Controller("GridView"))
        .MapRoute(r => r
            .RouteType(GridViewRouteType.UpdateRow)
            .Action("ResponsiveLayoutUpdateRow")
            .Controller("GridView")))
    .Settings(settings => settings.ShowFooter(true))
    .CssClasses(classes => classes
        .Row("grid-nowrap-row")
        .Control("grid-borderless"))
    .SettingsPager(settings => settings
        .PageSize(16)
        .NumericButtonCount(6)
        .PageSizeItemSettings(pageSize => pageSize
            .Items("8", "16", "30", "50", "100")
            .Visible(true)))
    .Bind(Model))

Adaptive Mode

The adaptive layout mode allows the Grid View to automatically switch to a compact presentation when the screen resolution becomes less than or equal to the specified value. In this presentation, each data entry's fields are displayed within an adaptive detail row.

Call the AdaptivityMode method (available through SettingsAdaptivity) with the HideDataCellsWindowLimit argument to enable the adaptive layout mode.

Scroll to the Grid View displayed below and toggle between screen orientations using the corresponding buttons on the right to see the adaptive behavior in action:

@model IEnumerable<EditableProduct>
@(Html.DevExpress()
    .BootstrapGridView<EditableProduct>("gridAdaptiveLayout")
    .SettingsAdaptivity(settings => settings
        .AdaptivityMode(GridViewAdaptivityMode.HideDataCellsWindowLimit)
        .HideDataCellsAtWindowInnerWidth(600)
        .AdaptiveDetailColumnCount(1))
    .KeyFieldName(m => m.ProductID)
    .Columns(columns => {
        columns
            .AddCommandColumn()
            .ShowEditButton(true)
            .Width(50);
        columns.Add(m => m.ProductName);
        columns.Add(m => m.QuantityPerUnit);
        columns
            .AddSpinEditColumn(m => m.UnitPrice)
            .PropertiesSpinEdit(p => p
                .DisplayFormatString("c")
                .DisplayFormatInEditMode(true)
                .MinValue(0)
                .MaxValue(60000))
            .Width(100);
        columns
            .AddSpinEditColumn(m => m.UnitsInStock)
            .PropertiesSpinEdit(p => p
                .MinValue(0)
                .MaxValue(10000))
            .Width(110);
        columns
            .AddCheckColumn(m => m.Discontinued)
            .PropertiesCheckEdit(p => p
                .AllowGrayed(true)
                .AllowGrayedByClick(false))
            .Width(100);
    })
    .TotalSummary(summary =>
        summary
            .Add()
            .FieldName("ProductName")
            .SummaryType(SummaryItemType.Count))
    .Settings(settings => settings.ShowFooter(true))
    .SettingsPager(settings => settings
        .PageSize(9)
        .NumericButtonCount(6)
        .PageSizeItemSettings(pageSize => pageSize
            .Items("2", "9", "15", "30", "50")
            .Visible(true)))
    .Routes(routes => routes
        .MapRoute(r => r
            .Action("AdaptiveLayoutPartial")
            .Controller("GridView"))
        .MapRoute(r => r
            .RouteType(GridViewRouteType.UpdateRow)
            .Action("AdaptiveLayoutUpdateRow")
            .Controller("GridView")))
    .CssClasses(css => css.Control("grid-borderless"))
    .Bind(Model))

Adaptive Mode with Form Layout

The adaptive detail row shown in the adaptive mode inherits the Form Layout functionality to arrange its items. You can specify layout settings for the adaptive detail row by calling the AdaptiveDetailLayoutProperties method (available through SettingsAdaptivity). The Items method available through AdaptiveDetailLayoutProperties allows you to specify which items should be displayed in the adaptive detail row.

Use an item's ColumnName method to associate it with a data column.

@model AdaptiveLayoutWithFormLayoutModel
@(Html.DevExpress()
    .BootstrapGridView<EditableProduct>("gridAdaptiveLayoutWithFormLayout")
    .SettingsAdaptivity(settings => settings
        .AdaptivityMode(GridViewAdaptivityMode.HideDataCellsWindowLimit)
        .HideDataCellsAtWindowInnerWidth(600)
        .AdaptiveDetailLayoutProperties(p => p
            .Items(i => {
                i.Add()
                    .ColumnName("Commands")
                    .ColSpanSm(12);
                i.Add(m => m.ProductName)
                    .ColSpanSm(12);
                i.Add(m => m.CategoryID)
                   .ColSpanSm(12);
                i.Add(m => m.QuantityPerUnit)
                   .ColSpanSm(12);
                i.Add(m => m.UnitsInStock)
                   .ColSpanSm(12);
                i.Add(m => m.UnitPrice)
                   .ColSpanSm(12);
                i.Add(m => m.Discontinued)
                   .ColSpanSm(12);
            })))
    .KeyFieldName(m => m.ProductID)
    .Columns(columns => {
        columns
            .AddCommandColumn()
            .ShowEditButton(true)
            .Width(50)
            .Name("Commands");
        columns.Add(m => m.ProductName);
        columns
            .AddComboBoxColumn(m => m.CategoryID)
            .Caption("Category Name")
            .Width(100)
            .GroupIndex(0)
            .PropertiesComboBox(p => p
                .ValueType(typeof(int))
                .ValueField("CategoryID")
                .TextField("CategoryName")
                .Bind(Model.Categories));
        columns
            .Add(m => m.QuantityPerUnit);
        columns
            .AddSpinEditColumn(m => m.UnitPrice)
            .Width(100)
            .PropertiesSpinEdit(p => p
                .DisplayFormatString("c")
                .DisplayFormatInEditMode(true)
                .MinValue(0)
                .MaxValue(60000));
        columns
            .AddSpinEditColumn(m => m.UnitsInStock)
            .Width(110)
            .PropertiesSpinEdit(p => p
                .MinValue(0)
                .MaxValue(10000));
        columns
            .AddCheckColumn(m => m.Discontinued)
            .Width(100)
            .PropertiesCheckEdit(p => p
                .AllowGrayed(true)
                .AllowGrayedByClick(false));
    })
    .TotalSummary(summary =>
        summary
            .Add()
            .FieldName("ProductName")
            .SummaryType(SummaryItemType.Count))
    .Settings(settings => settings
        .ShowFooter(true)
        .ShowGroupPanel(true))
    .SettingsEditing(settings => settings
       .Mode(GridViewEditingMode.EditForm))
    .SettingsPager(settings => settings
        .PageSize(6)
        .NumericButtonCount(6)
        .PageSizeItemSettings(pageSize => pageSize
            .Items("2", "6", "12", "20", "50")
            .Visible(true)))
    .Routes(routes => routes
        .MapRoute(r => r
            .Action("AdaptiveLayoutWithFormLayoutPartial")
            .Controller("GridView"))
        .MapRoute(r => r
            .RouteType(GridViewRouteType.UpdateRow)
            .Action("AdaptiveLayoutWithFormLayoutUpdateRow")
            .Controller("GridView")))
    .CssClasses(css => css.Control("grid-borderless"))
    .OnBeforeRender((s, e) => {
        if(!s.IsPartialUpdate)
            s.ExpandRow(0);
    })
    .Bind(Model.Products))

Adaptive Mode with Adaptive Form Layout

This demo illustrates how to take advantage of the Form Layout functionality to control which data items are displayed within the adaptive detail row and how they adapt to the different screen resolutions.

A layout item provides settings allowing you to define how it is sized using the Bootstrap grid system functionality:

@model AdaptiveLayoutWithFormLayoutModel
@(Html.DevExpress()
    .BootstrapGridView<EditableProduct>("gridAdaptiveLayoutWithAdaptiveFormLayout")
    .SettingsAdaptivity(settings => settings
        .AdaptivityMode(GridViewAdaptivityMode.HideDataCellsWindowLimit)
        .HideDataCellsAtWindowInnerWidth(1000)
        .AdaptiveDetailLayoutProperties(p => p
            .Items(i => {
                i.Add()
                    .ColumnName("Commands")
                    .ColSpanSm(12);
                i.Add(m => m.ProductName)
                    .ColSpanSm(6);
                i.Add(m => m.CategoryID)
                   .ColSpanSm(6);
                i.Add(m => m.QuantityPerUnit)
                   .ColSpanSm(6)
                   .BeginRow(true);
                i.Add(m => m.UnitsInStock)
                   .ColSpanSm(6);
                i.Add(m => m.UnitPrice)
                   .ColSpanSm(6);
                i.Add(m => m.Discontinued)
                   .ColSpanSm(6);
            })))
    .KeyFieldName(m => m.ProductID)
    .Columns(columns => {
        columns
            .AddCommandColumn()
            .ShowEditButton(true)
            .Width(50)
            .Name("Commands");
        columns.Add(m => m.ProductName);
        columns
            .AddComboBoxColumn(m => m.CategoryID)
            .Caption("Category Name")
            .Width(100)
            .GroupIndex(0)
            .PropertiesComboBox(p => p
                .ValueType(typeof(int))
                .ValueField("CategoryID")
                .TextField("CategoryName")
                .Bind(Model.Categories));
        columns
            .Add(m => m.QuantityPerUnit);
        columns
            .AddSpinEditColumn(m => m.UnitPrice)
            .Width(100)
            .PropertiesSpinEdit(p => p
                .DisplayFormatString("c")
                .DisplayFormatInEditMode(true)
                .MinValue(0)
                .MaxValue(60000));
        columns
            .AddSpinEditColumn(m => m.UnitsInStock)
            .Width(110)
            .PropertiesSpinEdit(p => p
                .MinValue(0)
                .MaxValue(10000));
        columns
            .AddCheckColumn(m => m.Discontinued)
            .Width(100)
            .PropertiesCheckEdit(p => p
                .AllowGrayed(true)
                .AllowGrayedByClick(false));
    })
    .TotalSummary(summary =>
        summary
            .Add()
            .FieldName("ProductName")
            .SummaryType(SummaryItemType.Count))
    .Settings(settings => settings
        .ShowFooter(true)
        .ShowGroupPanel(true))
    .SettingsEditing(settings => settings
       .Mode(GridViewEditingMode.EditForm))
    .SettingsPager(settings => settings
        .PageSize(6)
        .NumericButtonCount(6)
        .PageSizeItemSettings(pageSize => pageSize
            .Items("2", "6", "12", "20", "50")
            .Visible(true)))
    .Routes(routes => routes
        .MapRoute(r => r
            .Action("AdaptiveLayoutWithAdaptiveFormLayoutPartial")
            .Controller("GridView"))
        .MapRoute(r => r
            .RouteType(GridViewRouteType.UpdateRow)
            .Action("AdaptiveLayoutWithAdaptiveFormLayoutUpdateRow")
            .Controller("GridView")))
    .CssClasses(css => css.Control("grid-borderless"))
    .OnBeforeRender((s, e) => {
        if(!s.IsPartialUpdate)
            s.ExpandRow(0);
    })
    .Bind(Model.Products))

Adaptive Edit Form Layout

The layout of an edit form (including the popup edit form) can be customized using the Items method (available through SettingsEditing -> FormLayoutProperties).

A layout item’s ColSpanXX methods allow you to use the Bootstrap grid system functionality to align layout elements based on the display resolution.

If the Items collection is empty, the default layout is generated automatically.

Use an item’s ColumnName method to associate a layout item with a data column.

@model IEnumerable<EditableEmployee>
@(Html.DevExpress()
    .BootstrapGridView<EditableEmployee>("gridAdaptiveEditFormLayout")
    .Settings(settings => settings
        .ShowPreview(true))
    .KeyFieldName(m => m.ID)
    .PreviewFieldName(m => m.Notes)
    .Columns(columns => {
        columns
            .AddCommandColumn()
            .ShowEditButton(true)
            .Width(60);
        columns.AddTextColumn(m => m.FirstName);
        columns.AddTextColumn(m => m.LastName);
        columns.AddTextColumn(m => m.Title);
        columns.AddDateEditColumn(m => m.BirthDate).Width(100);
        columns.AddMemoColumn(m => m.Notes)
            .Visible(false)
            .PropertiesMemoEdit(props => props.Rows(4));
    })
    .SettingsEditing(settings => settings
        .FormLayoutProperties(props => props
            .Items(i => {
                i.Add(m => m.FirstName)
                    .ColSpanSm(6);
                i.Add(m => m.LastName)
                    .ColSpanSm(6);
                i.Add(m => m.Title)
                    .ColSpanSm(6);
                i.Add(m => m.BirthDate)
                    .ColSpanSm(6);
                i.Add(m => m.Notes)
                    .ColSpanSm(12);
                i.AddEditModeCommandItem()
                    .HorizontalAlign(FormLayoutHorizontalAlign.Right);
            })))
    .Routes(routes => routes
        .MapRoute(r => r
            .Action("AdaptiveEditFormLayoutPartial")
            .Controller("GridView"))
        .MapRoute(r => r
            .RouteType(GridViewRouteType.UpdateRow)
            .Action("AdaptiveEditFormLayoutUpdateRow")
            .Controller("GridView")))
    .CssClasses(css => css.Control("grid-borderless"))
    .OnBeforeRender((s, e) => {
        if(!s.IsPartialUpdate)
            s.StartEdit(0);
    })
    .Bind(Model))

Css Adaptivity

This demo illustrates how you can use the bootstrap classes' functionality to achieve granular control over the adaptive behavior of Grid View's visual elements. The Grid View control displayed below hides its Discontinued and Quantity per Unit columns when orientated vertically, after assigning column elements (data cells, header cells, and footer cells) to the d-none d-md-table-cell CSS classed provided by Bootstrap. Assigning this class specifies that the element should not be displayed when the Grid View is viewed with an extra small display resolution.

Similarly, some elements of the grid pager are assigned to the d-none d-md-block classed to provide a more compact pager presentation on extra small screens.

You can use other responsive utility classes to control the visibility of control elements with different screen sizes: Bootstrap responsive utility classes.

@model IEnumerable<EditableProduct>
@(Html.DevExpress()
    .BootstrapGridView<EditableProduct>("gridCssAdaptivity")
    .KeyFieldName(m => m.ProductID)
    .Columns(columns => {
        columns
            .AddCommandColumn()
            .ShowEditButton(true)
            .Width(50);
        columns.Add(m => m.ProductName);
        columns
            .Add(m => m.QuantityPerUnit)
            .CssClasses(c => c
                .DataCell("icon-column d-none d-md-table-cell")
                .HeaderCell("d-none d-md-table-cell")
                .FooterCell("d-none d-md-table-cell"));
        columns
            .AddSpinEditColumn(m => m.UnitPrice)
            .Width(100)
            .PropertiesSpinEdit(p => p
                .DisplayFormatString("c")
                .DisplayFormatInEditMode(true)
                .MinValue(0)
                .MaxValue(60000));
        columns
            .AddSpinEditColumn(m => m.UnitsInStock)
            .Width(110)
            .PropertiesSpinEdit(p => p
                .MinValue(0)
                .MaxValue(10000));
        columns
            .AddCheckColumn(m => m.Discontinued)
            .Width(100)
            .PropertiesCheckEdit(p => p
                .AllowGrayed(true)
                .AllowGrayedByClick(false))
            .CssClasses(c => c
                .DataCell("d-none d-md-table-cell")
                .HeaderCell("d-none d-md-table-cell")
                .FooterCell("d-none d-md-table-cell"));
    })
    .TotalSummary(summary =>
        summary
            .Add()
            .FieldName("ProductName")
            .SummaryType(SummaryItemType.Count))
    .Settings(settings => settings.ShowFooter(true))
    .SettingsEditing(editing => editing.Mode(GridViewEditingMode.EditForm))
    .SettingsPager(settings => settings
        .PageSize(14)
        .NumericButtonCount(6)
        .PageSizeItemSettings(pageSize => pageSize
            .Items("8", "14", "30", "50", "100")
            .Visible(true)))
    .Routes(route => route
        .MapRoute(r => r
            .Action("CssAdaptivityPartial")
            .Controller("GridView"))
        .MapRoute(r => r
            .RouteType(GridViewRouteType.UpdateRow)
            .Action("CssAdaptivityUpdateRow")
            .Controller("GridView")))
    .CssClasses(css => css.Control("grid-borderless"))
    .CssClassesPager(css => css
        .PageNumber("d-none d-md-block")
        .Ellipsis("d-none d-md-block")
        .Summary("d-none d-md-block"))
    .Bind(Model))
Screen Size
Color Themes
Demo QR Code