logo Devexpress WPF控件文档中心
文档首页>>Devexpress WPF控件文档中心>>DXSerializer事件-高级场景

DXSerializer事件-高级场景


立即下载DevExpress WPF

本主题描述DXSerializer事件的高级用例。

序列化/反序列化DevExpress WPF控件子类的自定义属性

保存/恢复自定义属性必须满足的要求

1.用[XtraSerializableProperty]属性标记属性。

在GridControl的后代中,您还应该为该属性分配以下属性之一:

  • 当DXSerializer.StoreLayoutMode为UI时,[GridUIProperty]属性用于保存/恢复自定义属性。
  • 当DXSerializer.StoreLayoutMode为None时,[GridStoreAlwaysProperty]属性用于保存/恢复自定义属性。

2.如果属性是依赖属性,请指定其本地值。

下面的代码示例保存/恢复MyCustomProperty依赖属性值:

XAML:

<Window
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:local="clr-namespace:GridSerialization"
xmlns:dxg="http://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="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxg="http://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
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP