Serialization and Deserialization in .NET MAUI DataGrid (SfDataGrid)
7 Jul 202622 minutes to read
SfDataGrid allows you to serialize and deserialize the SfDataGrid settings using DataContractSerializer.
By default, SfDataGrid serializes the following properties: column configurations, sorting, grouping, caption summaries, group summaries, table summaries, stacked headers, DetailsViewDefinition, and unbound rows. You can customize which features are serialized/deserialized using serialization options.
Serialization
You can serialize the SfDataGrid by using SfDataGrid.Serialize method which exports the current DataGrid control properties to an XML file.
string localPath = Path.Combine(FileSystem.AppDataDirectory, "DataGrid.xml");
using (var file = File.Create(localPath))
{
dataGrid.Serialize(file);
}Serialize as stream
You can store the SfDataGrid settings as Stream using Serialize method by passing the stream.
string filePath = "DataGrid";
using (FileStream stream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{
dataGrid.Serialize(stream);
}Serialization options
SfDataGrid serialization can be customized by passing a DataGridSerializationOptions instance to the Serialize method. By default, all options are enabled. Disable specific options to exclude certain grid features from serialization.
Serialize sorting
Disable sorting serialization by setting DataGridSerializationOptions.SerializeSorting to false.
string localPath = Path.Combine(FileSystem.AppDataDirectory, "DataGrid.xml");
using (var file = File.Create(localPath))
{
DataGridSerializationOptions options = new DataGridSerializationOptions();
options.SerializeSorting = false;
dataGrid.Serialize(file, options);
}Serialize grouping
Disable grouping serialization by setting DataGridSerializationOptions.SerializeGrouping to false.
string localPath = Path.Combine(FileSystem.AppDataDirectory, "DataGrid.xml");
using (var file = File.Create(localPath))
{
DataGridSerializationOptions options = new DataGridSerializationOptions();
options.SerializeGrouping = false;
dataGrid.Serialize(file, options);
}Serialize columns
Disable column manipulation serialization by setting DataGridSerializationOptions.SerializeColumns to false.
string localPath = Path.Combine(FileSystem.AppDataDirectory, "DataGrid.xml");
using (var file = File.Create(localPath))
{
DataGridSerializationOptions options = new DataGridSerializationOptions();
options.SerializeColumns = false;
dataGrid.Serialize(file, options);
}Serialize summaries
Disable caption, group, or table summary serialization by setting DataGridSerializationOptions.SerializeCaptionSummary, DataGridSerializationOptions.SerializeGroupSummaries, or DataGridSerializationOptions.SerializeTableSummaries to false.
string localPath = Path.Combine(FileSystem.AppDataDirectory, "DataGrid.xml");
using (var file = File.Create(localPath))
{
DataGridSerializationOptions options = new DataGridSerializationOptions();
options.SerializeCaptionSummary = false;
options.SerializeGroupSummaries = false;
options.SerializeTableSummaries = false;
dataGrid.Serialize(file, options);
}Serialize stacked headers
Disable stacked headers serialization by setting DataGridSerializationOptions.SerializeStackedHeaders to false.
string localPath = Path.Combine(FileSystem.AppDataDirectory, "DataGrid.xml");
using (var file = File.Create(localPath))
{
DataGridSerializationOptions options = new DataGridSerializationOptions();
options.SerializeStackedHeaders = false;
dataGrid.Serialize(file, options);
}Serialize Details View
Disable DetailsViewDefinition serialization by setting DataGridSerializationOptions.SerializeDetailsViewDefinition to false.
string localPath = Path.Combine(FileSystem.AppDataDirectory, "DataGrid.xml");
using (var file = File.Create(localPath))
{
DataGridSerializationOptions options = new DataGridSerializationOptions();
options.SerializeDetailsViewDefinition = false;
dataGrid.Serialize(file, options);
}Serialize unbound rows
Disable unbound rows serialization by setting DataGridSerializationOptions.SerializeUnboundRows to false.
string localPath = Path.Combine(FileSystem.AppDataDirectory, "DataGrid.xml");
using (var file = File.Create(localPath))
{
DataGridSerializationOptions options = new DataGridSerializationOptions();
options.SerializeUnboundRows = false;
dataGrid.Serialize(file, options);
}Deserialization
You can deserialize the SfDataGrid by using SfDataGrid.Deserialize method to reconstruct the grid based on settings stored in an XML file.
string localPath = Path.Combine(FileSystem.AppDataDirectory, "DataGrid.xml");
using (var file = File.Open(localPath, FileMode.Open))
{
dataGrid.Deserialize(file);
}Deserialize from stream
You can deserialize the SfDataGrid settings from Stream using Deserialize method.
FileStream fileStream = new FileStream("DataGrid", FileMode.Open);
dataGrid.Deserialize(fileStream);Deserialization options
Deserialization can be customized by passing a DataGridDeserializationOptions instance to the Deserialize method. By default, all options are enabled. Disable specific options to skip restoring certain grid features.
Deserialize sorting
Disable sorting restoration by setting DataGridDeserializationOptions.DeserializeSorting to false.
string localPath = Path.Combine(FileSystem.AppDataDirectory, "DataGrid.xml");
using (var file = File.Open(localPath, FileMode.Open))
{
DataGridDeserializationOptions options = new DataGridDeserializationOptions();
options.DeserializeSorting = false;
dataGrid.Deserialize(file, options);
}Deserialize grouping
Disable grouping restoration by setting DataGridDeserializationOptions.DeserializeGrouping to false.
string localPath = Path.Combine(FileSystem.AppDataDirectory, "DataGrid.xml");
using (var file = File.Open(localPath, FileMode.Open))
{
DataGridDeserializationOptions options = new DataGridDeserializationOptions();
options.DeserializeGrouping = false;
dataGrid.Deserialize(file, options);
}Deserialize columns
Disable column manipulation restoration by setting DataGridDeserializationOptions.DeserializeColumns to false.
string localPath = Path.Combine(FileSystem.AppDataDirectory, "DataGrid.xml");
using (var file = File.Open(localPath, FileMode.Open))
{
DataGridDeserializationOptions options = new DataGridDeserializationOptions();
options.DeserializeColumns = false;
dataGrid.Deserialize(file, options);
}Deserialize summaries
Disable caption, group, or table summary restoration by setting DataGridDeserializationOptions.DeserializeCaptionSummary, DataGridDeserializationOptions.DeserializeGroupSummaries, or DataGridDeserializationOptions.DeserializeTableSummaries to false.
string localPath = Path.Combine(FileSystem.AppDataDirectory, "DataGrid.xml");
using (var file = File.Open(localPath, FileMode.Open))
{
DataGridDeserializationOptions options = new DataGridDeserializationOptions();
options.DeserializeCaptionSummary = false;
options.DeserializeGroupSummaries = false;
options.DeserializeTableSummaries = false;
dataGrid.Deserialize(file, options);
}Deserialize stacked headers
Disable stacked headers restoration by setting DataGridDeserializationOptions.DeserializeStackedHeaders to false.
string localPath = Path.Combine(FileSystem.AppDataDirectory, "DataGrid.xml");
using (var file = File.Open(localPath, FileMode.Open))
{
DataGridDeserializationOptions options = new DataGridDeserializationOptions();
options.DeserializeStackedHeaders = false;
dataGrid.Deserialize(file, options);
}Deserialize Details View
Disable DetailsViewDefinition restoration by setting DataGridDeserializationOptions.DeserializeDetailsViewDefinition to false.
string localPath = Path.Combine(FileSystem.AppDataDirectory, "DataGrid.xml");
using (var file = File.Open(localPath, FileMode.Open))
{
DataGridDeserializationOptions options = new DataGridDeserializationOptions();
options.DeserializeDetailsViewDefinition = false;
dataGrid.Deserialize(file, options);
}Deserialize unbound rows
Disable unbound rows restoration by setting DataGridDeserializationOptions.DeserializeUnboundRows to false.
string localPath = Path.Combine(FileSystem.AppDataDirectory, "DataGrid.xml");
using (var file = File.Open(localPath, FileMode.Open))
{
DataGridDeserializationOptions options = new DataGridDeserializationOptions();
options.DeserializeUnBoundRows = false;
dataGrid.Deserialize(file, options);
}Customizing Serialization and Deserialization Operations
SfDataGrid allows you to customize the serialization and deserialization operations by deriving DataGridSerializationController class and override the necessary virtual methods.
Serialize custom column
By default, unknown column types are serialized as DataGridTextColumn. To serialize custom columns, register them in the serialization controller.
In the below code snippet, TextImageColumn is created.
public class TextImageColumn : DataGridColumn
{
public TextImageColumn()
{
var cellType = typeof(DataGridColumn).GetRuntimeProperties()
.FirstOrDefault(property => property.Name == "CellType");
cellType?.SetValue(this, "TextImage");
}
protected override void SetConverterForDisplayBinding()
{
base.SetConverterForDisplayBinding();
if (DisplayBinding is Binding binding)
{
binding.Converter = new CustomTextConverter();
}
}
public class CustomTextConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
=> value?.ToString();
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
=> value?.ToString();
}
}In the below code snippet, the TextImageColumn is defined in SfDataGrid.
<syncfusion:SfDataGrid x:Name="dataGrid"
AutoGenerateColumnsMode="None"
GridLinesVisibility="Both"
HeaderGridLinesVisibility="Both"
ItemsSource="{Binding Employees}">
<syncfusion:SfDataGrid.Columns>
<local:TextImageColumn HeaderText="Title"
MappingName="Title" />
</syncfusion:SfDataGrid.Columns>
</syncfusion:SfDataGrid>To serialize the above TextImageColumn, follow the below steps.
Step 1: Create a class derived from SerializableDataGridColumn and define the custom column properties in SerializableCustomGridColumn class.
[DataContract(Name = "SerializableCustomGridColumn")]
public class SerializableCustomGridColumn : SerializableDataGridColumn
{
[DataMember]
public string TextMappingName { get; set; }
}Step 2: Create a new class named as SerializationControllerExt by overriding DataGridSerializationController class.
dataGrid.SerializationController = new SerializationControllerExt(dataGrid);
public class SerializationControllerExt : DataGridSerializationController
{
public SerializationControllerExt(SfDataGrid dataGrid) : base(dataGrid)
{
}
}Step 3: You can get the custom column property settings for serialization by overriding the GetSerializableColumn virtual method.
public class SerializationControllerExt : DataGridSerializationController
{
public SerializationControllerExt(SfDataGrid dataGrid) : base(dataGrid) { }
protected override SerializableDataGridColumn GetSerializableColumn(DataGridColumn column)
{
if (column is TextImageColumn)
{
return new SerializableCustomGridColumn();
}
return base.GetSerializableColumn(column);
}
}Step 4: Store the custom column property settings during serialization by overriding the StoreColumnProperties virtual method.
public class SerializationControllerExt : DataGridSerializationController
{
public SerializationControllerExt(SfDataGrid dataGrid) : base(dataGrid)
{
}
protected override void StoreColumnProperties(DataGridColumn column, SerializableDataGridColumn serializableColumn)
{
base.StoreColumnProperties(column, serializableColumn);
if (column is TextImageColumn textImageColumn && serializableColumn is SerializableCustomGridColumn customColumn)
{
customColumn.TextMappingName = textImageColumn.MappingName;
}
}
}Step 5: Add the custom column in to known column types by overriding the KnownTypes virtual method.
public class SerializationControllerExt : DataGridSerializationController
{
public SerializationControllerExt(SfDataGrid dataGrid) : base(dataGrid)
{
}
public override Type[] KnownTypes()
{
var types = base.KnownTypes().ToList();
types.Add(typeof(SerializableCustomGridColumn));
return types.ToArray();
}
}Step 6: During deserialization, you can get the custom column settings from SerializableDataGridColumn by overriding GetColumn virtual method.
public class SerializationControllerExt : DataGridSerializationController
{
public SerializationControllerExt(SfDataGrid dataGrid) : base(dataGrid)
{
}
protected override DataGridColumn GetColumn(SerializableDataGridColumn serializableColumn)
{
if (serializableColumn is SerializableCustomGridColumn)
{
return new TextImageColumn();
}
return base.GetColumn(serializableColumn);
}
}Step 7: Now restore the custom column settings from SerializableDataGridColumn by overriding the RestoreColumnProperties virtual method.
public class SerializationControllerExt : DataGridSerializationController
{
public SerializationControllerExt(SfDataGrid dataGrid) : base(dataGrid)
{
}
protected override void RestoreColumnProperties(SerializableDataGridColumn serializableColumn, DataGridColumn column)
{
base.RestoreColumnProperties(serializableColumn, column);
if (column is TextImageColumn textImageColumn && serializableColumn is SerializableCustomGridColumn customColumn)
{
textImageColumn.MappingName = customColumn.TextMappingName;
}
}
}You can download the sample demo here
Serializing template column content
By default, you cannot serialize the template content in SfDataGrid because templates are XAML objects that cannot be serialized to XML. This limitation applies to DataTemplate, ControlTemplate, and other dynamic UI definitions. To work around this, you must reconstruct the templates during deserialization from stored resources or code-defined templates.
<ContentPage.Resources>
<ResourceDictionary>
<DataTemplate x:Key="cellTemplate">
<Button Text="Test" />
</DataTemplate>
</ResourceDictionary>
</ContentPage.Resources>
<syncfusion:SfDataGrid x:Name="dataGrid"
AutoGenerateColumnsMode="None"
GridLinesVisibility="Both"
HeaderGridLinesVisibility="Both"
ItemsSource="{Binding Employees}">
<syncfusion:SfDataGrid.Columns>
<syncfusion:DataGridTemplateColumn MappingName="Name"
HeaderText="Name"
CellTemplate="{StaticResource cellTemplate}" />
</syncfusion:SfDataGrid.Columns>
</syncfusion:SfDataGrid>If you want to serialize and deserialize the template content, you have to reconstruct the same template during deserialization in RestoreColumnProperties method.
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
this.dataGrid.SerializationController = new SerializationControllerExt(this.dataGrid,Resources);
this.dataGrid1.SerializationController = new SerializationControllerExt(this.dataGrid1,Resources);
}
}
public class SerializationControllerExt : DataGridSerializationController
{
private readonly ResourceDictionary _pageResources;
public SerializationControllerExt(SfDataGrid grid, ResourceDictionary pageResources)
: base(grid)
{
_pageResources = pageResources;
}
protected override void RestoreColumnProperties(SerializableDataGridColumn serializableColumn, DataGridColumn column)
{
base.RestoreColumnProperties(serializableColumn, column);
if (column is DataGridTemplateColumn templateColumn &&
string.Equals(templateColumn.MappingName, "Name", StringComparison.Ordinal))
{
if (_pageResources != null &&
_pageResources.TryGetValue("cellTemplate", out var template) &&
template is DataTemplate dataTemplate)
{
templateColumn.CellTemplate = dataTemplate;
}
}
}
}You can download the template serialization sample here to see a complete working example.