Example E4437
Visible to All Users

Grid View for ASP.NET Web Forms - How to save and restore the client layout

This example demonstrates how to save and restore the client layout of the Grid View control. In the example, the session state stores the grid layout in XML format. You can use any other storage instead of the session state.

The Grid View's ClientLayout event allows you to save the grid layout each time a user changes it and restore this layout on the first page load. Use the LayoutMode event argument to identify whether to save or restore the layout.

Files to Review

Documentation

More Examples

Example Code

WebSite/App_Code/ClientLayoutSerializer.cs(vb)
C#
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Web; using System.Web.UI.WebControls; using System.Xml; using System.Xml.Serialization; using DevExpress.Web; public class ClientLayoutSerializer { private ASPxGridView grid; private const string SessionPostfix = "_layoutData"; public ClientLayoutSerializer(ASPxGridView grid) { this.grid = grid; } public void RestoreClientLayout() { if (HttpContext.Current.Session[grid.ClientID + SessionPostfix] == null) return; string dataString = (String)HttpContext.Current.Session[grid.ClientID + SessionPostfix]; DeserializeColumns(dataString); } public void SaveClientLayout() { string data = SerializeColumns(); HttpContext.Current.Session[grid.ClientID + SessionPostfix] = data; } private string SerializeColumns() { StringBuilder sb = new StringBuilder(); using (XmlWriter xw = XmlWriter.Create(sb)) { xw.WriteStartDocument(); GridViewInfo g = new GridViewInfo(grid); foreach (GridViewColumn column in grid.Columns) { if (column is GridViewDataColumn) g.Columns.Add(new DataColumnInfo(column as GridViewDataColumn)); else if (column is GridViewCommandColumn) g.Columns.Add(new CommandColumnInfo(column as GridViewCommandColumn)); else if (column is GridViewBandColumn) g.Columns.Add(new BandColumnInfo(column as GridViewBandColumn)); } XmlSerializer xmlSerializer = new XmlSerializer(g.GetType()); xmlSerializer.Serialize(xw, g); } return sb.ToString(); } private void DeserializeColumns(string layoutData) { XmlDocument doc = new XmlDocument(); doc.LoadXml(layoutData); GridViewInfo gridInfo = null; XmlSerializer xmlSerializer = new XmlSerializer(typeof(GridViewInfo)); using (XmlReader xr = XmlReader.Create(new StringReader(layoutData))) { gridInfo = (GridViewInfo)xmlSerializer.Deserialize(xr); } gridInfo.RestoreGridViewLayout(grid); } }
WebSite/App_Code/ColumnInfo.cs(vb)
C#
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI.WebControls; using System.Xml.Serialization; using DevExpress.Data; using DevExpress.Web; [XmlInclude(typeof(DataColumnInfo))] [XmlInclude(typeof(CommandColumnInfo))] [XmlInclude(typeof(BandColumnInfo))] public abstract class ColumnInfoBase { public ColumnInfoBase() { } public ColumnInfoBase(GridViewColumn column) { Caption = column.Caption; Width = column.Width.ToString(); Name = column.Name; ExportWidth = column.ExportWidth; VisibleIndex = column.VisibleIndex; Visible = column.Visible; } public int VisibleIndex { get; set; } public string Width { get; set; } public bool Visible { get; set; } public string Name { get; set; } public string Caption { get; set; } public int ExportWidth { get; set; } public virtual void RestoreGridViewColumn(GridViewColumn column) { column.Caption = Caption; column.Width = Unit.Parse(Width); column.Name = Name; column.ExportWidth = ExportWidth; column.VisibleIndex = VisibleIndex; column.Visible = Visible; } } public class DataColumnInfo : ColumnInfoBase { public DataColumnInfo() { } public DataColumnInfo(GridViewDataColumn column) : base(column) { RealTypeName = column.GetType().ToString(); FieldName = column.FieldName; GroupIndex = column.GroupIndex; SortIndex = column.SortIndex; SortOrder = column.SortOrder; } public string RealTypeName { get; set; } public string FieldName { get; set; } public int GroupIndex { get; set; } public int SortIndex { get; set; } public ColumnSortOrder SortOrder { get; set; } public override void RestoreGridViewColumn(GridViewColumn column) { if (column == null) return; if (typeof(GridViewDataColumn).Assembly.GetType(RealTypeName) != column.GetType()) return; base.RestoreGridViewColumn(column); GridViewDataColumn c = (GridViewDataColumn)column; c.FieldName = FieldName; c.GroupIndex = GroupIndex; c.SortIndex = SortIndex; c.SortOrder = SortOrder; } } public sealed class CommandColumnInfo : ColumnInfoBase { public CommandColumnInfo() { } public CommandColumnInfo(GridViewCommandColumn column) : base(column) { ShowEditButton = column.ShowEditButton; ShowNewButton = column.ShowSelectButton; ShowDeleteButton = column.ShowDeleteButton; ShowSelectCheckbox = column.ShowSelectCheckbox; } public bool ShowEditButton { get; set; } public bool ShowNewButton { get; set; } public bool ShowDeleteButton { get; set; } public bool ShowSelectCheckbox { get; set; } public override void RestoreGridViewColumn(GridViewColumn column) { if (column == null) return; base.RestoreGridViewColumn(column); GridViewCommandColumn c = (GridViewCommandColumn)column; c.ShowEditButton = ShowEditButton; c.ShowNewButton = ShowNewButton; c.ShowDeleteButton = ShowDeleteButton; c.ShowSelectCheckbox = ShowSelectCheckbox; } } public sealed class BandColumnInfo : ColumnInfoBase { public BandColumnInfo() { } public BandColumnInfo(GridViewBandColumn column) : base(column) { } public override void RestoreGridViewColumn(GridViewColumn column) { if (column == null) return; base.RestoreGridViewColumn(column); GridViewBandColumn c = (GridViewBandColumn)column; //To-Do: Save child column information } }
WebSite/App_Code/GridViewInfo.cs(vb)
C#
using System; using System.Collections.Generic; using System.Linq; using System.Web; using DevExpress.Web; /// <summary> /// Summary description for GridViewInfo /// </summary> public class GridViewInfo { public GridViewInfo() { } public GridViewInfo(ASPxGridView grid) { Columns = new List<ColumnInfoBase>(grid.Columns.Count); FilterExpression = grid.FilterExpression; PageIndex = grid.PageIndex; } public List<ColumnInfoBase> Columns { get; set; } public string FilterExpression { get; set; } public int PageIndex { get; set; } public void RestoreGridViewLayout(ASPxGridView grid) { foreach (ColumnInfoBase column in Columns) { DataColumnInfo dataColumnInfo = column as DataColumnInfo; if (dataColumnInfo != null) { column.RestoreGridViewColumn(grid.Columns[dataColumnInfo.FieldName]); continue; } if (column is CommandColumnInfo) { column.RestoreGridViewColumn(GetSpecificColumn<GridViewCommandColumn>(grid)); continue; } if (column is BandColumnInfo) { column.RestoreGridViewColumn(GetSpecificColumn<GridViewBandColumn>(grid)); continue; } } grid.FilterExpression = FilterExpression; grid.PageIndex = PageIndex; } private T GetSpecificColumn<T>(ASPxGridView grid) where T : GridViewColumn { foreach (GridViewColumn c in grid.Columns) if (c is T) return (T)c; return null; } }
WebSite/Default.aspx
ASPx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <%@ Register Assembly="DevExpress.Web.v15.1, Version=15.1.15.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" Namespace="DevExpress.Web" TagPrefix="dx" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>How to implement custom saving in XML and restoring of ASPxGridView client layout</title> </head> <body> <form id="form1" runat="server"> <div style="float: left"> Categories:<br /> <dx:ASPxGridView runat="server" AutoGenerateColumns="False" DataSourceID="dsCategories" KeyFieldName="CategoryID" ID="grid1" ClientInstanceName="grid" Width="612px" OnClientLayout="grid_ClientLayout"> <SettingsBehavior ColumnResizeMode="NextColumn" /> <ClientSideEvents ColumnResized="function (s, e) { e.processOnServer = true; }" /> <Columns> <dx:GridViewDataTextColumn FieldName="CategoryID" ReadOnly="True" VisibleIndex="0"> <EditFormSettings Visible="False" /> </dx:GridViewDataTextColumn> <dx:GridViewDataTextColumn FieldName="CategoryName" VisibleIndex="1"> </dx:GridViewDataTextColumn> <dx:GridViewDataTextColumn FieldName="Description" VisibleIndex="2"> </dx:GridViewDataTextColumn> </Columns> <Settings ShowFilterBar="Visible" ShowFilterRow="True" ShowFilterRowMenu="True" /> </dx:ASPxGridView> </div> <div style="padding:20px 0 0 800px;"> <dx:ASPxHyperLink ID="ASPxHyperLink1" runat="server" Text="Re-open page in new windos" Target="_blank" NavigateUrl="~/Default.aspx"> </dx:ASPxHyperLink> </div> <div style="clear: both;"></div> <br /> <br /> Products:<br /> <dx:ASPxGridView runat="server" AutoGenerateColumns="False" DataSourceID="dsProducts" KeyFieldName="ProductID" ID="grid" ClientInstanceName="grid" OnClientLayout="grid_ClientLayout"> <SettingsBehavior ColumnResizeMode="NextColumn" /> <ClientSideEvents ColumnResized="function (s, e) { e.processOnServer = true; }" /> <Columns> <dx:GridViewCommandColumn VisibleIndex="0" ShowEditButton="True" ShowNewButton="True" ShowDeleteButton="True"/> <dx:GridViewDataTextColumn FieldName="ProductID" ReadOnly="True" VisibleIndex="1"> <EditFormSettings Visible="False" /> <EditFormSettings Visible="False"></EditFormSettings> </dx:GridViewDataTextColumn> <dx:GridViewDataTextColumn FieldName="ProductName" VisibleIndex="2"> </dx:GridViewDataTextColumn> <dx:GridViewDataTextColumn FieldName="SupplierID" VisibleIndex="3"> </dx:GridViewDataTextColumn> <dx:GridViewDataComboBoxColumn FieldName="CategoryID" VisibleIndex="4"> <PropertiesComboBox DataSourceID="dsCategories" TextField="CategoryName" ValueField="CategoryID" ValueType="System.Int32"> </PropertiesComboBox> </dx:GridViewDataComboBoxColumn> <dx:GridViewDataTextColumn FieldName="QuantityPerUnit" VisibleIndex="5"> </dx:GridViewDataTextColumn> <dx:GridViewDataTextColumn FieldName="UnitPrice" VisibleIndex="6"> </dx:GridViewDataTextColumn> <dx:GridViewDataTextColumn FieldName="UnitsInStock" VisibleIndex="7"> </dx:GridViewDataTextColumn> <dx:GridViewDataTextColumn FieldName="UnitsOnOrder" VisibleIndex="8"> </dx:GridViewDataTextColumn> <dx:GridViewDataTextColumn FieldName="ReorderLevel" VisibleIndex="9"> </dx:GridViewDataTextColumn> <dx:GridViewDataCheckColumn FieldName="Discontinued" VisibleIndex="10"> </dx:GridViewDataCheckColumn> </Columns> <Settings ShowFilterBar="Visible" ShowFilterRow="True" ShowFilterRowMenu="True" /> </dx:ASPxGridView> <br /> <br /> Employees:<br /> <dx:ASPxGridView runat="server" AutoGenerateColumns="False" DataSourceID="dsEmployee" KeyFieldName="EmployeeID" ID="grid0" ClientInstanceName="grid" Width="1476px" OnClientLayout="grid_ClientLayout"> <SettingsBehavior ColumnResizeMode="NextColumn" /> <ClientSideEvents ColumnResized="function (s, e) { e.processOnServer = true; }" /> <Columns> <dx:GridViewDataTextColumn FieldName="EmployeeID" ReadOnly="True" VisibleIndex="0"> <EditFormSettings Visible="False" /> </dx:GridViewDataTextColumn> <dx:GridViewDataTextColumn FieldName="LastName" VisibleIndex="1"> </dx:GridViewDataTextColumn> <dx:GridViewDataTextColumn FieldName="FirstName" VisibleIndex="2"> </dx:GridViewDataTextColumn> <dx:GridViewDataTextColumn FieldName="Title" VisibleIndex="3"> </dx:GridViewDataTextColumn> <dx:GridViewDataTextColumn FieldName="TitleOfCourtesy" VisibleIndex="4"> </dx:GridViewDataTextColumn> <dx:GridViewDataDateColumn FieldName="BirthDate" VisibleIndex="5"> </dx:GridViewDataDateColumn> <dx:GridViewDataDateColumn FieldName="HireDate" VisibleIndex="6"> </dx:GridViewDataDateColumn> <dx:GridViewDataTextColumn FieldName="Address" VisibleIndex="7"> </dx:GridViewDataTextColumn> <dx:GridViewDataTextColumn FieldName="City" VisibleIndex="8"> </dx:GridViewDataTextColumn> <dx:GridViewDataTextColumn FieldName="Region" VisibleIndex="9"> </dx:GridViewDataTextColumn> <dx:GridViewDataTextColumn FieldName="PostalCode" VisibleIndex="10"> </dx:GridViewDataTextColumn> <dx:GridViewDataTextColumn FieldName="Country" VisibleIndex="11"> </dx:GridViewDataTextColumn> <dx:GridViewDataTextColumn FieldName="HomePhone" VisibleIndex="12"> </dx:GridViewDataTextColumn> <dx:GridViewDataTextColumn FieldName="Extension" VisibleIndex="13"> </dx:GridViewDataTextColumn> <dx:GridViewDataTextColumn FieldName="Notes" VisibleIndex="14"> </dx:GridViewDataTextColumn> <dx:GridViewDataTextColumn FieldName="ReportsTo" VisibleIndex="15"> </dx:GridViewDataTextColumn> <dx:GridViewDataTextColumn FieldName="PhotoPath" VisibleIndex="16"> </dx:GridViewDataTextColumn> </Columns> <Settings ShowFilterBar="Visible" ShowFilterRow="True" ShowFilterRowMenu="True" /> </dx:ASPxGridView> <div style="padding:20px 0 0 800px;"> <dx:ASPxHyperLink ID="ASPxHyperLink2" runat="server" Text="Re-open page in new windos" Target="_blank" NavigateUrl="~/Default.aspx"> </dx:ASPxHyperLink> </div> <asp:SqlDataSource ID="dsProducts" runat="server" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" SelectCommand="SELECT [ProductID], [ProductName], [SupplierID], [CategoryID], [QuantityPerUnit], [UnitPrice], [UnitsInStock], [UnitsOnOrder], [ReorderLevel], [Discontinued] FROM [Products]"></asp:SqlDataSource> <asp:SqlDataSource ID="dsCategories" runat="server" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" SelectCommand="SELECT [CategoryID], [CategoryName], [Description] FROM [Categories]"></asp:SqlDataSource> <asp:SqlDataSource ID="dsEmployee" runat="server" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" SelectCommand="SELECT [EmployeeID], [LastName], [FirstName], [Title], [TitleOfCourtesy], [BirthDate], [HireDate], [Address], [City], [Region], [PostalCode], [Country], [HomePhone], [Photo], [Extension], [Notes], [ReportsTo], [PhotoPath] FROM [Employees]"></asp:SqlDataSource> </form> </body> </html>
WebSite/Default.aspx.cs(vb)
C#
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using DevExpress.Web; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected void grid_ClientLayout(object sender, ASPxClientLayoutArgs e) { ASPxGridView g = sender as ASPxGridView; ClientLayoutSerializer serializer = new ClientLayoutSerializer(g); if (e.LayoutMode == ClientLayoutMode.Loading) serializer.RestoreClientLayout(); else serializer.SaveClientLayout(); } }

Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.