You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

控件全属性(反)序列化难题:寻求简便实现方案

控件属性序列化的简化实现方案

问题场景

尝试对控件所有属性进行序列化,测试DevExpress TextEdit和TextBox控件时发现:仅无子项或非枚举类型的属性可直接通过(反)序列化转换为字符串完成操作。目前手动为各控件属性编写单独规则工作量极大,尤其兼容不同厂商控件时难度更高,求更简便的实现方式。

当前实现代码(VB.NET)

Public Class ControlProperties
    Public Property Text As String
    Public Property BackColor As String
    Public Property BorderStyle As Integer
    Public Property Size As Size
    Public Property Location As Point
    Public Property ForeColor As String
    Public Property Multiline As Boolean
    Public Property AllowDrop As Boolean
    Public Property Cursor As String
    Public Property RightToLeft As RightToLeft
    Public Property Font As SerializableFont
End Class

Public Class SerializableFont
    Public Property Name As String
    Public Property Size As Single
    Public Property Style As FontStyle

    Public Sub New()
    End Sub

    Public Sub New(font As Font)
        Name = font.Name
        Size = font.Size
        Style = font.Style
    End Sub

    Public Function ToFont() As Font
        Return New Font(Name, Size, Style)
    End Function
End Class

Public Sub SerializeControlProperties(control As Object, filePath As String)
    Dim properties As New ControlProperties()
    properties.Text = control.Text
    properties.BackColor = ColorTranslator.ToHtml(control.BackColor)
    properties.BorderStyle = control.BorderStyle
    properties.Size = control.Size
    properties.Location = control.Location
    properties.ForeColor = ColorTranslator.ToHtml(control.ForeColor)
    properties.AllowDrop = control.AllowDrop
    properties.Cursor = CursorToString(control.Cursor)
    properties.RightToLeft = control.RightToLeft
    properties.Font = New SerializableFont(control.Font)

    Dim serializer As New XmlSerializer(GetType(ControlProperties))

    Using writer As TextWriter = New StreamWriter(filePath)
        serializer.Serialize(writer, properties)
    End Using
End Sub

生成的XML示例

<?xml version="1.0" encoding="utf-8"?>
<ControlProperties xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Text />
  <BackColor>#FFFFFF</BackColor>
  <BorderStyle>7</BorderStyle>
  <Size>
    <Width>100</Width>
    <Height>20</Height>
  </Size>
  <Location>
    <X>221</X>
    <Y>26</Y>
  </Location>
  <ForeColor>#282828</ForeColor>
  <Multiline>false</Multiline>
  <AllowDrop>false</AllowDrop>
  <Cursor>System.Windows.Forms.Cursor</Cursor>
  <RightToLeft>No</RightToLeft>
  <Font>
    <Name>Tahoma</Name>
    <Size>8.25</Size>
    <Style>Regular</Style>
  </Font>
</ControlProperties>

简化实现方案

1. 利用反射自动遍历属性,减少手动赋值

通过反射获取控件公共属性,自动判断类型并处理序列化转换,无需手动定义ControlProperties类:

Imports System.Reflection
Imports System.Xml.Serialization

Public Sub SerializeControlByReflection(control As Control, filePath As String)
    Dim overrides As New XmlAttributeOverrides()
    ' 注册Color、Font、Cursor的自定义序列化逻辑
    AddColorSerializer(overrides)
    AddFontSerializer(overrides)
    AddCursorSerializer(overrides)

    Dim serializer As New XmlSerializer(control.GetType(), overrides)
    Using writer As New StreamWriter(filePath)
        serializer.Serialize(writer, control)
    End Using
End Sub

Private Sub AddColorSerializer(overrides As XmlAttributeOverrides)
    Dim colorAttrs As New XmlAttributes()
    colorAttrs.XmlSerializer = New XmlSerializer(GetType(String))
    overrides.Add(GetType(Color), colorAttrs)
End Sub

Private Sub AddFontSerializer(overrides As XmlAttributeOverrides)
    Dim fontAttrs As New XmlAttributes()
    fontAttrs.XmlSerializer = New XmlSerializer(GetType(SerializableFont))
    overrides.Add(GetType(Font), fontAttrs)
End Sub

Private Sub AddCursorSerializer(overrides As XmlAttributeOverrides)
    Dim cursorAttrs As New XmlAttributes()
    cursorAttrs.XmlSerializer = New XmlSerializer(GetType(String))
    overrides.Add(GetType(Cursor), cursorAttrs)
End Sub

2. 复用第三方控件自带的序列化机制

多数第三方控件(如DevExpress)自带布局序列化方法,直接调用即可:

' DevExpress TextEdit序列化示例
Dim textEdit As New DevExpress.XtraEditors.TextEdit()
textEdit.SaveLayoutToXml("textEditLayout.xml")
' 反序列化
textEdit.RestoreLayoutFromXml("textEditLayout.xml")

WinForms原生控件可借助System.ComponentModel.TypeDescriptor获取属性的序列化字符串,或复用PropertyGrid的序列化能力。

3. 使用Json.NET替代XmlSerializer,简化复杂类型处理

Json.NET对WinForms复杂类型支持更友好,仅需少量自定义转换器:

Imports Newtonsoft.Json
Imports Newtonsoft.Json.Converters

' 自定义Color转换器
Public Class ColorConverter
    Inherits JsonConverter(Of Color)
    Public Overrides Sub WriteJson(writer As JsonWriter, value As Color, serializer As JsonSerializer)
        writer.WriteValue(ColorTranslator.ToHtml(value))
    End Sub

    Public Overrides Function ReadJson(reader As JsonReader, objectType As Type, existingValue As Color, hasExistingValue As Boolean, serializer As JsonSerializer) As Color
        Return ColorTranslator.FromHtml(reader.Value.ToString())
    End Function
End Class

' 自定义Font转换器
Public Class FontConverter
    Inherits JsonConverter(Of Font)
    Public Overrides Sub WriteJson(writer As JsonWriter, value As Font, serializer As JsonSerializer)
        serializer.Serialize(writer, New SerializableFont(value))
    End Sub

    Public Overrides Function ReadJson(reader As JsonReader, objectType As Type, existingValue As Font, hasExistingValue As Boolean, serializer As JsonSerializer) As Font
        Dim serializableFont = serializer.Deserialize(Of SerializableFont)(reader)
        Return serializableFont.ToFont()
    End Function
End Class

' 序列化示例
Public Sub SerializeControlToJson(control As Control, filePath As String)
    Dim settings As New JsonSerializerSettings()
    settings.Converters.Add(New ColorConverter())
    settings.Converters.Add(New FontConverter())
    settings.Formatting = Formatting.Indented

    Dim json = JsonConvert.SerializeObject(control, settings)
    File.WriteAllText(filePath, json)
End Sub

4. 封装通用序列化工具类

将类型转换逻辑封装成通用方法,注册一次转换器即可复用,无需为每个控件编写单独规则。

内容的提问来源于stack exchange,提问作者nidzolino

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 03:45:12