DXSerializer事件-高级场景
本主题描述DXSerializer事件的高级用例。
序列化/反序列化DevExpress WPF控件子类的自定义属性
保存/恢复自定义属性必须满足的要求
1.用[XtraSerializableProperty]属性标记属性。
在GridControl的后代中,您还应该为该属性分配以下属性之一:
- 当DXSerializer.StoreLayoutMode为UI时,[GridUIProperty]属性用于保存/恢复自定义属性。
- 当DXSerializer.StoreLayoutMode为None时,[GridStoreAlwaysProperty]属性用于保存/恢复自定义属性。
2.如果属性是依赖属性,请指定其本地值。
下面的代码示例保存/恢复MyCustomProperty依赖属性值:
XAML:
<Window xmlns:dx="//schemas.devexpress.com/winfx/2008/xaml/core" xmlns:local="clr-namespace:GridSerialization" xmlns:dxg="//schemas.devexpress.com/winfx/2008/xaml/grid" x:Class="GridSerialization.MainWindow"> <StackPanel> <local:GridControlEx dx:DXSerializer.StoreLayoutMode="UI" x:Name="grid" MyCustomProperty="15"> <dxg:GridControl.View> <dxg:TableView/> </dxg:GridControl.View> </local:GridControlEx> </StackPanel> </Window>
C# :
using DevExpress.Utils.Serializing;
using DevExpress.Xpf.Grid;
using DevExpress.Xpf.Core.Serialization;
public class GridControlEx : GridControl {
public static DependencyProperty MyCustomPropertyProperty =
DependencyProperty.Register("MyCustomProperty", typeof(int), typeof(GridControlEx));
[XtraSerializableProperty]
[GridStoreAlwaysProperty]
public int MyCustomProperty {
get => (int)GetValue(MyCustomPropertyProperty);
set => SetValue(MyCustomPropertyProperty, value);
}
}
VB.NET:
Imports DevExpress.Utils.Serializing
Imports DevExpress.Xpf.Grid
Imports DevExpress.Xpf.Core.Serialization
Public Class GridControlEx
Inherits GridControl
Public Shared MyCustomPropertyProperty As DependencyProperty = DependencyProperty.Register("MyCustomProperty", GetType(Integer), GetType(GridControlEx))
<XtraSerializableProperty>
<GridStoreAlwaysProperty>
Public Property MyCustomProperty As Integer
Get
Return CInt(GetValue(MyCustomPropertyProperty))
End Get
Set(ByVal value As Integer)
Return SetValue(MyCustomPropertyProperty, value)
End Set
End Property
End Class
序列化自定义附加属性
要序列化自定义附加属性,请使用[xtrasserializableproperty]属性标记该属性的Get方法。
C# :
public static readonly DependencyProperty IsCheckedProperty =
DependencyProperty.RegisterAttached("IsChecked", typeof(bool), typeof(GridControlEx), new PropertyMetadata(false));
[XtraSerializableProperty]
public static bool GetIsChecked(DependencyObject obj) {
return (bool)obj.GetValue(IsCheckedProperty);
}
public static void SetIsChecked(DependencyObject obj, bool value) {
obj.SetValue(IsCheckedProperty, value);
}
VB.NET:
Public Shared ReadOnly IsCheckedProperty As DependencyProperty = DependencyProperty.RegisterAttached("IsChecked", GetType(Boolean), GetType(GridControlEx), New PropertyMetadata(False))
<XtraSerializableProperty>
Public Shared Function GetIsChecked(ByVal obj As DependencyObject) As Boolean
Return CBool(obj.GetValue(IsCheckedProperty))
End Function
Public Shared Sub SetIsChecked(ByVal obj As DependencyObject, ByVal value As Boolean)
obj.SetValue(IsCheckedProperty, value)
End Sub
序列化标准和自定义控件
要保存/恢复自定义控件和标准控件的属性,请执行以下操作:
1.为要保存/恢复其布局的控件指定SerializationID属性。
2.用[XtraSerializableProperty]属性标记要保存/恢复其值的控件属性。
3.做以下其中一件事:
将属性传递给DXSerializer.AddCustomGetSerializablePropertiesHandler方法。
处理CustomGetSerializableProperties事件并将属性传递给CustomGetSerializablePropertiesEventArgs.SetPropertySerializable方法。
不恢复控件的预定义属性
执行以下操作来防止属性反序列化:
1.处理AllowProperty事件。
2.设置AllowPropertyEventArgs,允许属性为false。
您可以使用AllowPropertyEventArgs.Property来获得一个反序列化的属性。
下面的代码示例禁用了GridControl列的WidthProperty的反序列化操作:
MainWindow.xaml.cs:
using DevExpress.Xpf.Core.Serialization;
using DevExpress.Xpf.Grid;
// ...
public partial class MainWindow : Window {
public MainWindow() {
//...
grid.Columns[nameof(Customer.ID)].AddHandler(DXSerializer.AllowPropertyEvent,
new AllowPropertyEventHandler(OnAllowProperty));
}
void OnAllowProperty(object sender, AllowPropertyEventArgs e) {
if (e.DependencyProperty == GridColumn.WidthProperty)
e.Allow = false;
}
}
MainWindow.xaml.vb:
Imports DevExpress.Xpf.Core.Serialization Imports DevExpress.Xpf.Grid '... Public Partial Class MainWindow Inherits Window Public Sub New() ' ... grid.Columns(NameOf(Customer.ID)).[AddHandler](DXSerializer.AllowPropertyEvent, New AllowPropertyEventHandler(AddressOf OnAllowProperty)) End Sub Private Sub OnAllowProperty(ByVal sender As Object, ByVal e As AllowPropertyEventArgs) If e.DependencyProperty = GridColumn.WidthProperty Then e.Allow = False End Sub End Class
停止布局恢复(反序列化)
1.处理BeforeLoadLayout事件。
2.将BeforeLoadLayoutEventArgs.Allow事件参数设置为false。
下面的代码示例禁用GridControl的属性反序列化,如果布局版本不是1.48:
MainWindow.xaml.cs:
using DevExpress.Utils.Serializing;
using DevExpress.Xpf.Core.Serialization;
using DevExpress.Xpf.Grid;
using DevExpress.Xpf.Core;
// ...
public partial class MainWindow : Window {
public MainWindow() {
//...
grid.AddHandler(DXSerializer.BeforeLoadLayoutEvent, new BeforeLoadLayoutEventHandler(BeforeLoadLayoutHandler));
}
void BeforeLoadLayoutHandler(object sender, BeforeLoadLayoutEventArgs e) {
if (e.RestoredVersion != "1.48") {
e.Allow = false;
}
}
}
MainWindow.xaml.vb:
Imports DevExpress.Utils.Serializing Imports DevExpress.Xpf.Core.Serialization Imports DevExpress.Xpf.Grid Imports DevExpress.Xpf.Core '... Public Partial Class MainWindow Inherits Window Public Sub New() InitializeComponent() Me.DataContext = Me grid.[AddHandler](DXSerializer.BeforeLoadLayoutEvent, New BeforeLoadLayoutEventHandler(AddressOf BeforeLoadLayoutHandler)) End Sub Sub BeforeLoadLayoutHandler(ByVal sender As Object, ByVal e As BeforeLoadLayoutEventArgs) e.Allow = False End Sub End Class
从已保存(序列化)集合恢复项
- 处理CreateCollectionItem事件。
- 创建要恢复的集合对象的实例。
- 将创建的实例添加到e.Collection事件参数中。
- 设置e.CollectionItem为创建对象的实例。
例如,GridControl处理此事件来恢复列、摘要项、MRU过滤器等。
如果属性被标记为[xtrasserialableproperty]属性,则引发此事件,XtraSerializableProperty.XtraSerializationVisibility属性必须设置为xXtraSerializationVisibility.Collection,XtraSerializableProperty.UseCreateItem属性应该设置为true。
C# :
using DevExpress.Utils.Serializing;
using DevExpress.Xpf.Core.Serialization;
using DevExpress.Xpf.Grid;
using DevExpress.Xpf.Core;
// ...
public partial class MainWindow : Window {
public MainWindow() {
//...
grid.Columns["Name"].AddHandler(DXSerializer.CreateCollectionItemEvent, new XtraCreateCollectionItemEventHandler(OnCreateCollectionItem));
}
void OnCreateCollectionItem(object sender, XtraCreateCollectionItemEventArgs e) {
if (e.CollectionName == nameof(MyGridColumn.SomeCollection)) {
CustomObject item = new CustomObject();
((ObservableCollection<CustomObject>)e.Collection).Add(item);
e.CollectionItem = item;
}
}
public class MyGridColumn : GridColumn {
[XtraSerializableProperty(XtraSerializationVisibility.Collection, true, false, true)]
public ObservableCollection<CustomObject> SomeCollection {
get { return (ObservableCollection<CustomObject>)GetValue(SomeCollectionProperty); }
set { SetValue(SomeCollectionProperty, value); }
}
public static readonly DependencyProperty SomeCollectionProperty = DependencyProperty.Register("SomeCollection", typeof(ObservableCollection<CustomObject>), typeof(MyGridColumn), null);
}
public class CustomObject : INotifyPropertyChanged {
string itemID;
string itemValue;
[XtraSerializableProperty]
public string ItemID {
get {
return itemID;
}
set {
itemID = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("ItemID"));
}
}
[XtraSerializableProperty]
public string ItemValue {
get {
return itemValue;
}
set {
itemValue = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("PropertyB"));
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName) {
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public class Customer {
public int ID {
get;
set;
}
public string Name {
get;
set;
}
}
}
VB.NET:
Imports DevExpress.Utils.Serializing
Imports DevExpress.Xpf.Core.Serialization
Imports DevExpress.Xpf.Grid
Imports DevExpress.Xpf.Core
Public Partial Class MainWindow
Inherits Window
Public Sub New()
grid.Columns("Name").[AddHandler](DXSerializer.CreateCollectionItemEvent, New XtraCreateCollectionItemEventHandler(AddressOf OnCreateCollectionItem))
End Sub
Private Sub OnCreateCollectionItem(ByVal sender As Object, ByVal e As XtraCreateCollectionItemEventArgs)
Dim item As CustomObject = New CustomObject()
(CType(e.Collection, ObservableCollection(Of CustomObject))).Add(item)
e.CollectionItem = item
End Sub
End Class
保存可视树中不存在的控件
处理CustomGetSerializableChildren事件。
添加一个控件,它的布局要保存到CustomGetSerializableChildrenEventArgs.Children集合。
如果一个LayoutPanel包含一个UserControl和一个GridControl,并且这个面板没有被激活,GridControl在可视树中不存在,并且它的属性没有被保存(序列化)。要保存GridControl的属性,将GridControl添加到CustomGetSerializableChildrenEventArgs.Children集合中。
MainWindow.xaml.cs:
using DevExpress.Utils.Serializing;
using DevExpress.Xpf.Core.Serialization;
using DevExpress.Xpf.Grid;
using DevExpress.Xpf.Core;
using DevExpress.Xpf.Docking;
// ...
public partial class MainWindow : Window {
public MainWindow() {
//...
layoutPanel.AddHandler(DXSerializer.CustomGetSerializableChildrenEvent, new CustomGetSerializableChildrenEventHandler(CustomGetSerializableChildrenEventHandler));
}
///...
void OnCreateContentPropertyValue(object sender, XtraCreateContentPropertyValueEventArgs e) {
e.Children.Add(grid);
}
}
MainWindow.xaml.vb:
Imports DevExpress.Utils.Serializing Imports DevExpress.Xpf.Core.Serialization Imports DevExpress.Xpf.Grid Imports DevExpress.Xpf.Core Imports DevExpress.Xpf.Docking '... Public Partial Class MainWindow Inherits Window Public Sub New() '... layoutPanel.[AddHandler](DXSerializer.CustomGetSerializableChildrenEvent, New CustomGetSerializableChildrenEventHandler(CustomGetSerializableChildrenEventHandler)) End Sub '... Sub OnCreateContentPropertyValue(ByVal sender As Object, ByVal e As XtraCreateContentPropertyValueEventArgs) e.Children.Add(grid) End Sub End Class
序列化没有被xtrasserializable属性标记的属性
1.处理CustomGetSerializableProperties事件。
2.将要保存/恢复其值的属性传递给CustomGetSerializablePropertiesEventArgs.SetPropertySerializable方法。
下面的代码示例保存(序列化)GridColumn.Tag属性:
C# :
using DevExpress.Utils.Serializing;
using DevExpress.Xpf.Core.Serialization;
using DevExpress.Xpf.Grid;
using DevExpress.Xpf.Core;
//...
public partial class MainWindow : Window {
public MainWindow() {
//...
grid.AddHandler(DXSerializer.CustomGetSerializablePropertiesEvent, new CustomGetSerializablePropertiesEventHandler(CustomGetSerializablePropertiesHandler));
}
void CustomGetSerializablePropertiesHandler(object sender, CustomGetSerializablePropertiesEventArgs e) {
e.SetPropertySerializable(GridColumn.TagProperty, new DXSerializable() { });
}
}
VB.NET:
Imports DevExpress.Utils.Serializing Imports DevExpress.Xpf.Core.Serialization Imports DevExpress.Xpf.Grid Imports DevExpress.Xpf.Core '... Public Partial Class MainWindow Inherits Window Public Sub New() InitializeComponent() Me.DataContext = Me grid.[AddHandler](DXSerializer.CustomGetSerializablePropertiesEvent, New CustomGetSerializablePropertiesEventHandler(CustomGetSerializablePropertiesHandler)) End Sub Sub CustomGetSerializablePropertiesHandler(ByVal sender As Object, ByVal e As CustomGetSerializablePropertiesEventArgs) e.SetPropertySerializable(GridColumn.TagProperty, New DXSerializable()) End Sub End Class
在应用程序的不同版本之间更新布局
执行以下操作并在较新的应用程序版本中更新应用程序的布局:
1.指定或增加DXSerializer.LayoutVersion附加的属性值,此属性是应用程序布局的版本。
2.更改应用程序的布局。
3.如果应用程序的DXSerializer.LayoutVersion附加属性值低于新属性值,则触发LayoutUpgrade事件。
提示:DXSerializer.AddXXXHandler方法只适用于UI元素。如果一个元素是FrameworkContentElement的后代,则使用标准的AddHandler方法。
创建自定义属性反序列化处理程序
当属性被反序列化时,将发生DeserializeProperty事件,您可以使用XtraPropertyInfoEventArgs.Name/XtraPropertyInfoEventArgs.DependencyProperty获取属性/依赖属性的名称。
XAML:
<Window ... xmlns:dx="//schemas.devexpress.com/winfx/2008/xaml/core" xmlns:dxg="//schemas.devexpress.com/winfx/2008/xaml/grid"> <DockPanel> <!-- ... --> <dxg:GridControl x:Name="grid" dx:DXSerializer.DeserializeProperty="grid_DeserializeProperty"> <!-- ... --> </dxg:GridControl> </DockPanel> </Window>
C# :
private void grid_DeserializeProperty(object sender, DevExpress.Xpf.Core.Serialization.XtraPropertyInfoEventArgs e) {
if (e.DependencyProperty == ColumnBase.VisibleProperty) {
e.Handled = true;
// ...
}
}
VB.NET:
Private Sub grid_DeserializeProperty(ByVal sender As Object, ByVal e As DevExpress.Xpf.Core.Serialization.XtraPropertyInfoEventArgs) If e.DependencyProperty = ColumnBase.VisibleProperty Then e.Handled = True '... End If End Sub

QQ交谈
在线咨询

渝公网安备
50010702500608号

客服热线