New to Telerik UI for WPF? Download free 30-day trial

Persistence

The implementation demonstrated in this article can also be reviewed in the Persist QueryableDataProvider SDK Example of the SDK Examples Browser

This article will go through the process of persisting the current state of QueryableDataProvider via RadPersistenceFramework. Through it the state of the control can be persisted and loaded the next time the application is started.

Using the DataContract Attribute

The DataContract attribute is added to all classes used by the QueryableDataProvider. This enables easy serialization with the DataContractSerializer. Below is a sample definition of such classes. The DataContract attribute is added on class level and the DataMember one is added for each property.

Example 1: Using the DataContract attribute

[DataContract] 
public class DataProviderSettings 
{ 
    [DataMember] 
    public object[] Aggregates { get; set; } 
 
    [DataMember] 
    public object[] Filters { get; set; } 
 
    [DataMember] 
    public object[] Rows { get; set; } 
 
    [DataMember] 
    public object[] Columns { get; set; } 
 
    [DataMember] 
    public int AggregatesLevel { get; set; } 
 
    [DataMember] 
    public PivotAxis AggregatesPosition { get; set; } 
} 

Defining the IValueProvider

The next step is to create a new class, which implements the Telerik.Windows.Persistence.Services.IValueProvider interface. It provides two methods that need to be implemented - ProvideValue and RestoreValue. The first one is used when the data is saved. The second one is used when the data is restored from a previously saved state. When saving the provider, an instance of the DataProviderSettings class has to be created with all of its properties set. Then, the instance can be saved to a file or a stream. Below is a sample implementation of the interface.

Example 2: Implementing the IValueProvider interface

public abstract class DataProviderValueProvider : IValueProvider 
{ 
    public abstract IEnumerable<Type> KnownTypes { get; } 
 
    public string ProvideValue(object context) 
    { 
        string serialized = string.Empty; 
 
        IDataProvider dataProvider = context as IDataProvider; 
        if (dataProvider != null) 
        { 
            MemoryStream stream = new MemoryStream(); 
 
            DataProviderSettings settings = new DataProviderSettings() 
            { 
                Aggregates = dataProvider.Settings.AggregateDescriptions.OfType<object>().ToArray(), 
                Filters = dataProvider.Settings.FilterDescriptions.OfType<object>().ToArray(), 
                Rows = dataProvider.Settings.RowGroupDescriptions.OfType<object>().ToArray(), 
                Columns = dataProvider.Settings.ColumnGroupDescriptions.OfType<object>().ToArray(), 
                AggregatesLevel = dataProvider.Settings.AggregatesLevel, 
                AggregatesPosition = dataProvider.Settings.AggregatesPosition 
            }; 
 
            DataContractSerializer serializer = new DataContractSerializer(typeof(DataProviderSettings), KnownTypes); 
            serializer.WriteObject(stream, settings); 
 
            stream.Position = 0; 
            var streamReader = new StreamReader(stream); 
            serialized += streamReader.ReadToEnd(); 
        } 
 
        return serialized; 
    } 
 
    public void RestoreValue(object context, string savedValue) 
    { 
        IDataProvider dataProvider = context as IDataProvider; 
        if (dataProvider != null) 
        { 
            var stream = new MemoryStream(); 
            var tw = new StreamWriter(stream); 
            tw.Write(savedValue); 
            tw.Flush(); 
            stream.Position = 0; 
 
            DataContractSerializer serializer = new DataContractSerializer(typeof(DataProviderSettings), KnownTypes); 
            var result = serializer.ReadObject(stream); 
 
            dataProvider.Settings.AggregateDescriptions.Clear(); 
            foreach (var aggregateDescription in (result as DataProviderSettings).Aggregates) 
            { 
                dataProvider.Settings.AggregateDescriptions.Add(aggregateDescription); 
            } 
 
            dataProvider.Settings.FilterDescriptions.Clear(); 
            foreach (var filterDescription in (result as DataProviderSettings).Filters) 
            { 
                dataProvider.Settings.FilterDescriptions.Add(filterDescription); 
            } 
 
            dataProvider.Settings.RowGroupDescriptions.Clear(); 
            foreach (var rowDescription in (result as DataProviderSettings).Rows) 
            { 
                dataProvider.Settings.RowGroupDescriptions.Add(rowDescription); 
            } 
 
            dataProvider.Settings.ColumnGroupDescriptions.Clear(); 
            foreach (var columnDescription in (result as DataProviderSettings).Columns) 
            { 
                dataProvider.Settings.ColumnGroupDescriptions.Add(columnDescription); 
            } 
 
            dataProvider.Settings.AggregatesPosition = (result as DataProviderSettings).AggregatesPosition; 
            dataProvider.Settings.AggregatesLevel = (result as DataProviderSettings).AggregatesLevel; 
        } 
    } 
} 

Specifying the KnownTypes

In the previous example a collection of KnownTypes is passed to the DataContractSerializer. It consists of all types needed for serializing the QueryableDataProvider. For this purpose we created a new QueryablePivotSerializationHelper class which has a static member - KnownTypes.

Example 3: Specifying the KnownTypes

 public class QueryableDataSourceValueProvider: DataProviderValueProvider 
{ 
    public override IEnumerable<Type> KnownTypes 
    { 
        get  
        { 
            return QueryablePivotSerializationHelper.KnownTypes; 
        } 
    } 
} 

Registering the PersistenceProvider

The final step is to register a persistence provider and implement the logic needed for saving and loading the state of the QueryableDataProvider.

Example 4: Registering the PersistenceProvider

Stream stream = new MemoryStream(); 
 
ServiceProvider.RegisterPersistenceProvider<IValueProvider>(typeof(QueryableDataProvider), new QueryableDataSourceValueProvider()); 
//saving 
PersistenceManager manager = new PersistenceManager(); 
this.stream = manager.Save(this.PivotGrid.DataProvider); 
//loading 
this.stream.Position = 0; 
PersistenceManager manager = new PersistenceManager(); 
manager.Load(this.PivotGrid.DataProvider, this.stream); 

See Also

In this article