The following example shows how to implement a custom serializer.Custom serializers are required when data source field values are custom objects (not numeric or string values). In this example, the data source contains a Sales Person field whose values are Employee objects, exposing the FirstName, LastName and Age properties. The Employee class implements the IComparable interface, and overrides the GetHashCode, Equals and ToString methods (required to display and handle custom objects).The custom serializer is represented by the CustomObjectConverter class, which implements the ICustomObjectConverter interface. The ToString and FromString methods are implemented to serialize and deserialize the Employee objects, respectively. A CustomObjectConverter class instance is assigned to the PivotGridOptionsData.CustomObjectConverter property. It is used for serializing Sales Person field values when data is sorted or filtered. You can also use the Save and Load buttons to save the pivot grid layout to a string and restored it, respectively, which also implies field values serialization with the custom serializer.
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs"
Inherits="ASPxPivotGrid_CustomObjectConverter._Default" %>
<%@ Register Assembly="DevExpress.Web.ASPxEditors.v11.1, Version=11.1.5.0,
Culture=neutral, PublicKeyToken=b88d1754d700e49a"
Namespace="DevExpress.Web.ASPxEditors" TagPrefix="dx" %>
<%@ Register Assembly="DevExpress.Web.ASPxPivotGrid.v11.1, Version=11.1.5.0,
Culture=neutral, PublicKeyToken=b88d1754d700e49a"
Namespace="DevExpress.Web.ASPxPivotGrid" 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>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<table>
<tr>
<td>
<table>
<tr>
<td>
<dx:ASPxButton ID="ASPxButton1" runat="server"
Text="Save" OnClick="ASPxButton1_Click">
</dx:ASPxButton>
</td>
<td>
<dx:ASPxButton ID="ASPxButton2" runat="server"
Text="Load" OnClick="ASPxButton2_Click">
</dx:ASPxButton>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>
<dx:ASPxPivotGrid ID="ASPxPivotGrid1" runat="server">
<Fields>
<dx:PivotGridField ID="fieldProductName" Area="RowArea"
AreaIndex="0" Caption="Product Name"
FieldName="ProductName">
</dx:PivotGridField>
<dx:PivotGridField ID="fieldSalesPerson" Area="ColumnArea"
AreaIndex="0" Caption="Sales Person"
FieldName="SalesPerson">
</dx:PivotGridField>
<dx:PivotGridField ID="fieldQuantity" Area="DataArea"
AreaIndex="0" Caption="Quantity"
FieldName="Quantity">
</dx:PivotGridField>
</Fields>
</dx:ASPxPivotGrid>
</td>
</tr>
</table>
</div>
</form>
</body>
</html>
using System;
using System.IO;
using System.Web.UI;
using DevExpress.Utils.Serializing.Helpers;
namespace ASPxPivotGrid_CustomObjectConverter {
public partial class _Default : Page {
protected override void OnInit(EventArgs e) {
base.OnInit(e);
ASPxPivotGrid1.DataSource = DataHelper.GetData();
ASPxPivotGrid1.OptionsData.CustomObjectConverter = new CustomObjectConverter();
}
// Handles the Save button's Click event to save pivot grid data to a stream
// (requires data source serialization).
protected void ASPxButton1_Click(object sender, EventArgs e) {
Session["Layout"] = ASPxPivotGrid1.SaveLayoutToString();
}
// Handles the Load button's Click event to load pivot grid data from a stream
// (requires stream content deserialization).
protected void ASPxButton2_Click(object sender, EventArgs e) {
string layout = (string)Session["Layout"];
if (layout == null) {
return;
}
ASPxPivotGrid1.LoadLayoutFromString(layout);
}
}
// Implements a custom serializer.
public class CustomObjectConverter : ICustomObjectConverter {
// Returns a value, indicating whether objects of the specified type
// can be serialized/deserialized.
public bool CanConvert(Type type) {
return type == typeof(Employee);
}
// Deserializes objects of the specified type.
public object FromString(Type type, string str) {
if (type != typeof(Employee))
return null;
string[] array = str.Split('#');
if (array.Length >= 3)
return new Employee(array[0], array[1], int.Parse(array[2]));
else if (array.Length == 2)
return new Employee(array[0], array[1], 0);
else if (array.Length == 1)
return new Employee(array[0], string.Empty, 0);
else
return new Employee(string.Empty, string.Empty, 0);
}
// Serializes objects of the specified type.
public string ToString(Type type, object obj) {
if (type != typeof(Employee))
return string.Empty;
Employee value = obj as Employee;
return value.FirstName + '#' + value.LastName + '#' + value.Age;
}
// Returns the type by its full name.
public Type GetType(string typeName) {
if (typeName != typeof(Employee).FullName)
return null;
return typeof(Employee);
}
}
}
using System;
using System.Collections;
using System.Data;
namespace ASPxPivotGrid_CustomObjectConverter {
class Employee : IComparable {
string fFirstName, fLastName;
int fAge;
public Employee(string firstName, string lastName, int age) {
FirstName = firstName;
LastName = lastName;
Age = age;
}
public string FirstName {
get { return fFirstName; }
set { fFirstName = value; }
}
public string LastName {
get { return fLastName; }
set { fLastName = value; }
}
public int Age {
get { return fAge; }
set { fAge = value; }
}
public override int GetHashCode() {
return ToString().GetHashCode();
}
public override bool Equals(object obj) {
return CompareTo(obj) == 0;
}
public override string ToString() {
return FirstName + ' ' + LastName;
}
#region IComparable Members
public int CompareTo(object obj) {
Employee value = obj as Employee;
return Comparer.Default.Compare(ToString(), value.ToString());
}
#endregion
}
class DataHelper {
public static DataTable GetData() {
DataTable dt = new DataTable();
dt.Columns.Add("ProductName", typeof(string));
dt.Columns.Add("Quantity", typeof(int));
dt.Columns.Add("SalesPerson", typeof(Employee));
dt.Rows.Add("Alice Mutton", 250, new Employee("Janet", "Leverling", 23));
dt.Rows.Add("Geitost", 120, new Employee("Andrew", "Fuller", 32));
dt.Rows.Add("Chai", 70, new Employee("Anne", "Dodsworth", 43));
dt.Rows.Add("Chocolade", 15, new Employee("Andrew", "Fuller", 32));
dt.Rows.Add("Filo Mix", 9, new Employee("Anne", "Dodsworth", 43));
dt.Rows.Add("Alice Mutton", 63, new Employee("Andrew", "Fuller", 32));
dt.Rows.Add("Chai", 99, new Employee("Janet", "Leverling", 23));
return dt;
}
}
}
Imports Microsoft.VisualBasic
Imports System
Imports System.Collections
Imports System.Data
Namespace ASPxPivotGrid_CustomObjectConverter
Friend Class Employee
Implements IComparable
Private fFirstName, fLastName As String
Private fAge As Integer
Public Sub New(ByVal firstName As String, ByVal lastName As String, ByVal age As Integer)
Me.FirstName = firstName
Me.LastName = lastName
Me.Age = age
End Sub
Public Property FirstName() As String
Get
Return fFirstName
End Get
Set(ByVal value As String)
fFirstName = value
End Set
End Property
Public Property LastName() As String
Get
Return fLastName
End Get
Set(ByVal value As String)
fLastName = value
End Set
End Property
Public Property Age() As Integer
Get
Return fAge
End Get
Set(ByVal value As Integer)
fAge = value
End Set
End Property
Public Overrides Function GetHashCode() As Integer
Return ToString().GetHashCode()
End Function
Public Overrides Overloads Function Equals(ByVal obj As Object) As Boolean
Return CompareTo(obj) = 0
End Function
Public Overrides Function ToString() As String
Return FirstName & " "c + LastName
End Function
#Region "IComparable Members"
Public Function CompareTo(ByVal obj As Object) As Integer Implements IComparable.CompareTo
Dim value As Employee = TryCast(obj, Employee)
Return Comparer.Default.Compare(ToString(), value.ToString())
End Function
#End Region
End Class
Friend Class DataHelper
Public Shared Function GetData() As DataTable
Dim dt As New DataTable()
dt.Columns.Add("ProductName", GetType(String))
dt.Columns.Add("Quantity", GetType(Integer))
dt.Columns.Add("SalesPerson", GetType(Employee))
dt.Rows.Add("Alice Mutton", 250, New Employee("Janet", "Leverling", 23))
dt.Rows.Add("Geitost", 120, New Employee("Andrew", "Fuller", 32))
dt.Rows.Add("Chai", 70, New Employee("Anne", "Dodsworth", 43))
dt.Rows.Add("Chocolade", 15, New Employee("Andrew", "Fuller", 32))
dt.Rows.Add("Filo Mix", 9, New Employee("Anne", "Dodsworth", 43))
dt.Rows.Add("Alice Mutton", 63, New Employee("Andrew", "Fuller", 32))
dt.Rows.Add("Chai", 99, New Employee("Janet", "Leverling", 23))
Return dt
End Function
End Class
End Namespace
<%@ Page Language="vb" AutoEventWireup="true" CodeBehind="Default.aspx.vb"
Inherits="ASPxPivotGrid_CustomObjectConverter._Default" %>
<%@ Register Assembly="DevExpress.Web.ASPxEditors.v11.1, Version=11.1.6.0,
Culture=neutral, PublicKeyToken=b88d1754d700e49a"
Namespace="DevExpress.Web.ASPxEditors" TagPrefix="dx" %>
<%@ Register Assembly="DevExpress.Web.ASPxPivotGrid.v11.1, Version=11.1.6.0,
Culture=neutral, PublicKeyToken=b88d1754d700e49a"
Namespace="DevExpress.Web.ASPxPivotGrid" 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>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<table>
<tr>
<td>
<table>
<tr>
<td>
<dx:ASPxButton ID="ASPxButton1" runat="server"
Text="Save" OnClick="ASPxButton1_Click">
</dx:ASPxButton>
</td>
<td>
<dx:ASPxButton ID="ASPxButton2" runat="server"
Text="Load" OnClick="ASPxButton2_Click">
</dx:ASPxButton>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>
<dx:ASPxPivotGrid ID="ASPxPivotGrid1" runat="server">
<Fields>
<dx:PivotGridField ID="fieldProductName" Area="RowArea"
AreaIndex="0" Caption="Product Name"
FieldName="ProductName">
</dx:PivotGridField>
<dx:PivotGridField ID="fieldSalesPerson" Area="ColumnArea"
AreaIndex="0" Caption="Sales Person"
FieldName="SalesPerson">
</dx:PivotGridField>
<dx:PivotGridField ID="fieldQuantity" Area="DataArea"
AreaIndex="0" Caption="Quantity"
FieldName="Quantity">
</dx:PivotGridField>
</Fields>
</dx:ASPxPivotGrid>
</td>
</tr>
</table>
</div>
</form>
</body>
</html>
Imports Microsoft.VisualBasic
Imports System
Imports System.IO
Imports System.Web.UI
Imports DevExpress.Utils.Serializing.Helpers
Namespace ASPxPivotGrid_CustomObjectConverter
Partial Public Class _Default
Inherits Page
Protected Overrides Sub OnInit(ByVal e As EventArgs)
MyBase.OnInit(e)
ASPxPivotGrid1.DataSource = DataHelper.GetData()
ASPxPivotGrid1.OptionsData.CustomObjectConverter = New CustomObjectConverter()
End Sub
' Handles the Save button's Click event to save pivot grid data to a stream
' (requires data source serialization).
Protected Sub ASPxButton1_Click(ByVal sender As Object, ByVal e As EventArgs)
Session("Layout") = ASPxPivotGrid1.SaveLayoutToString()
End Sub
' Handles the Load button's Click event to load pivot grid data from a stream
' (requires stream content deserialization).
Protected Sub ASPxButton2_Click(ByVal sender As Object, ByVal e As EventArgs)
Dim layout As String = CStr(Session("Layout"))
If layout Is Nothing Then
Return
End If
ASPxPivotGrid1.LoadLayoutFromString(layout)
End Sub
End Class
' Implements a custom serializer.
Public Class CustomObjectConverter
Implements ICustomObjectConverter
' Returns a value, indicating whether objects of the specified type
' can be serialized/deserialized.
Public Function CanConvert(ByVal type As Type) As Boolean Implements ICustomObjectConverter.CanConvert
Return type Is GetType(Employee)
End Function
' Deserializes objects of the specified type.
Public Function FromString(ByVal type As Type, ByVal str As String) As Object Implements ICustomObjectConverter.FromString
If type IsNot GetType(Employee) Then
Return Nothing
End If
Dim array() As String = str.Split("#"c)
If array.Length >= 3 Then
Return New Employee(array(0), array(1), Integer.Parse(array(2)))
ElseIf array.Length = 2 Then
Return New Employee(array(0), array(1), 0)
ElseIf array.Length = 1 Then
Return New Employee(array(0), String.Empty, 0)
Else
Return New Employee(String.Empty, String.Empty, 0)
End If
End Function
' Serializes objects of the specified type.
Public Overloads Function ToString(ByVal type As Type, ByVal obj As Object) As String Implements ICustomObjectConverter.ToString
If type IsNot GetType(Employee) Then
Return String.Empty
End If
Dim value As Employee = TryCast(obj, Employee)
Return value.FirstName + "#"c + value.LastName + "#"c + value.Age
End Function
' Returns the type by its full name.
Public Overloads Function [GetType](ByVal typeName As String) As Type Implements ICustomObjectConverter.GetType
If typeName IsNot GetType(Employee).FullName Then
Return Nothing
End If
Return GetType(Employee)
End Function
End Class
End Namespace