C#用户控件设计时序列化

本文关键字:序列化 用户 控件 | 更新日期: 2023-09-27 18:00:08

背景

我正在开发自定义winforms控件。控件合并了使用某个公共属性公开的DataGridView控件。

我已经实现了自定义DesignerActionList和ControlDesigner,以便为DataGridView列操作(添加、删除、更改属性值)提供可视化接口。这很好:当我将控件添加到新表单时,可以添加列,并在设计时显示。sceenshot

目前,我即将实现将列状态保存到{Control}的功能。Designer.cs

我已经实现了自定义Deisger序列化程序如下:

    public class GridDesignerSerializer : CodeDomSerializer
    {
        public override object Serialize(IDesignerSerializationManager manager, object value)
        {
            var baseSerializer = (CodeDomSerializer)manager.GetSerializer(
                    typeof(Grid).BaseType,
                    typeof(CodeDomSerializer));
            object codeObject = baseSerializer.Serialize(manager, value);
            // now add some custom code
            if (codeObject is CodeStatementCollection)
            {
                // add a custom comment to the code.
                var statements = (CodeStatementCollection)codeObject;
                statements.Add(new CodeCommentStatement("This is GridDesignerSerializer generated code BEGIN:"));
                // HERE COMPONENT INITIALIZATION INVOKES WILL BE PLACED.
                    statements.Add(new CodeCommentStatement("This is GridDesignerSerializer generated code :END"));
            }
            return codeObject;
        }
    }

以及附加的控制类序列化属性:

[Designer(typeof(Grid_Designer))]
[DesignerSerializer(typeof(GridDesignerSerializer), typeof(CodeDomSerializer))]
public partial class Grid : UserControl
{ ...

问题

当我在设计时将新列添加到我的自定义控件DataGridView中时,设计器不会检测到任何更改(vs文档选项卡没有*)。因此,当我关闭设计视图时,序列化并没有发生。

当我更改一个其他控件属性(比如:更改边框样式)时,会检测到更改并执行自定义序列化(设计器中会显示其他注释)。

问题

  1. 如何通知Desiger更改的位置(添加列的位置),并执行序列化?

  2. GridDesignerSerializer中,如何引用设计时的DataGridView实例来迭代添加的列以执行代码生成?

谢谢你的建议。

C#用户控件设计时序列化

好的,我认为第1点用以下方法解决了

我添加了我的控制类内部:

    private IComponentChangeService GetChangeService()
    {
        return (IComponentChangeService)GetService(typeof(IComponentChangeService));
    }

然后在负责更改检测的方法/属性内部:

this.GetChangeService().OnComponentChanged(this, null, null, null);

因此,当我将列添加到DataGridView时,*会显示在文档选项卡上,并且在保存自定义序列化后执行。

第2点也是:在我的情况下,在GridDesignerSerializer:中添加以下代码

var grid = ((Grid)value);
statements.Add(new CodeCommentStatement("Column Count:" + grid.List.Columns.Count.ToString()));

序列化对象的实例通常是Serialize方法的第二个自变量:

Serialize(IDesignerSerializationManager manager, object value)