演练:序列化标准类型集合

自定义控件有时会将集合显示为属性。 本演练演示如何使用 DesignerSerializationVisibilityAttribute 类来控制集合在设计时如何序列化。 将 Content 值应用于集合属性可确保对属性进行序列化。

谨慎

此内容是为 .NET Framework 编写的。 如果使用 .NET 6 或更高版本,请谨慎使用此内容。 设计器系统已针对 Windows 窗体进行更改,因此请务必查看自 .NET Framework 以来对设计器所做的更改一文。

若要将本主题中的代码复制为单个列表,请参阅 如何:使用 DesignerSerializationVisibilityAttribute序列化标准类型的集合。

先决条件

需要 Visual Studio 才能完成本演练。

使用可序列化集合创建控件

第一步是创建具有可序列化集合作为属性的控件。 可以使用 集合编辑器编辑此集合的内容,可以从 属性 窗口中访问该编辑器。

  1. 在 Visual Studio 中创建 Windows 控件库项目,并将其命名为 SerializationDemoControlLib

  2. UserControl1 重命名为 SerializationDemoControl。 有关更多信息,请参阅重命名代码符号重构

  3. 属性 窗口中,将 Padding.All 属性的值设置为 10

  4. TextBox 控件置于 SerializationDemoControl中。

  5. 选择 TextBox 控件。 在 属性 窗口中,设置以下属性。

    财产 更改为
    多行 true
    停靠 Fill
    ScrollBars Vertical
    ReadOnly true
  6. 代码编辑器中,在 SerializationDemoControl中声明名为 stringsValue 的字符串数组字段。

        // This field backs the Strings property.
    private:
        array<String^>^ stringsValue;
    
    
    
    // This field backs the Strings property.
    private String[] stringsValue = new String[1];
    
    ' This field backs the Strings property.
     Private stringsValue(1) As String
    
  7. 定义 SerializationDemoControl上的 Strings 属性。

    说明

    Content 值用于启用集合的序列化。

        // When the DesignerSerializationVisibility attribute has
        // a value of "Content" or "Visible" the designer will 
        // serialize the property. This property can also be edited 
        // at design time with a CollectionEditor.
    public:
        [DesignerSerializationVisibility(
            DesignerSerializationVisibility::Content)]
        property array<String^>^ Strings
        {
            array<String^>^ get()
            {
                return this->stringsValue;
            }
            void set(array<String^>^ value)
            {
                this->stringsValue = value;
    
                // Populate the contained TextBox with the values
                // in the stringsValue array.
                StringBuilder^ sb =
                    gcnew StringBuilder(this->stringsValue->Length);
    
                for (int i = 0; i < this->stringsValue->Length; i++)
                {
                    sb->Append(this->stringsValue[i]);
                    sb->Append(Environment::NewLine);
                }
    
                this->demoControlTextBox->Text = sb->ToString();
            }
        }
    
    // When the DesignerSerializationVisibility attribute has
    // a value of "Content" or "Visible" the designer will
    // serialize the property. This property can also be edited
    // at design time with a CollectionEditor.
    [DesignerSerializationVisibility(
        DesignerSerializationVisibility.Content )]
    public String[] Strings
    {
        get
        {
            return this.stringsValue;
        }
        set
        {
            this.stringsValue = value;
    
            // Populate the contained TextBox with the values
            // in the stringsValue array.
            StringBuilder sb =
                new StringBuilder(this.stringsValue.Length);
    
            for (int i = 0; i < this.stringsValue.Length; i++)
            {
                sb.Append(this.stringsValue[i]);
                sb.Append("\r\n");
            }
    
            this.textBox1.Text = sb.ToString();
        }
    }
    
    ' When the DesignerSerializationVisibility attribute has
    ' a value of "Content" or "Visible" the designer will 
    ' serialize the property. This property can also be edited 
    ' at design time with a CollectionEditor.
     <DesignerSerializationVisibility( _
         DesignerSerializationVisibility.Content)> _
     Public Property Strings() As String()
         Get
             Return Me.stringsValue
         End Get
         Set(ByVal value As String())
             Me.stringsValue = Value
    
             ' Populate the contained TextBox with the values
             ' in the stringsValue array.
             Dim sb As New StringBuilder(Me.stringsValue.Length)
    
             Dim i As Integer
             For i = 0 To (Me.stringsValue.Length) - 1
                 sb.Append(Me.stringsValue(i))
                 sb.Append(ControlChars.Cr + ControlChars.Lf)
             Next i
    
             Me.textBox1.Text = sb.ToString()
         End Set
     End Property
    
  8. F5 生成项目并在 UserControl 测试容器中运行控件。

  9. UserControl 测试容器PropertyGrid 中查找 字符串 属性。 选择 Strings 属性,然后选择省略号 (Visual Studio 的属性窗口中的省略号按钮 (...)) 按钮以打开“字符串集合编辑器”

  10. 输入多个字符串到 字符串集合编辑器中。 使用 Enter 键在每个字符串末尾对它们进行分隔。 输入完字符串后,单击OK

说明

所键入的字符串随即显示在 SerializationDemoControlTextBox 中。

序列化集合属性

若要测试控件的序列化行为,请将它放在窗体上,并使用 集合编辑器更改集合的内容。 可以通过查看 Windows 窗体设计器向其中发出代码的特殊设计器文件来查看序列化集合状态

  1. 将 Windows 应用程序项目添加到解决方案。 将项目命名为 SerializationDemoControlTest

  2. 工具箱中,找到名为 SerializationDemoControlLib 组件的选项卡。 在此选项卡中,你将找到 SerializationDemoControl。 有关详细信息,请参阅 操作指南:使用自定义组件自动填充工具箱

  3. 在窗体上放置一个 SerializationDemoControl

  4. 属性 窗口中查找 Strings 属性。 单击 Strings 属性,然后单击 Visual Studio“属性”窗口中的省略号(省略号按钮(...)。)按钮打开 字符串集合编辑器

  5. 字符串集合编辑器中键入多个字符串。 通过在每个字符串末尾按 Enter 键来将它们分开。 输入完字符串后单击“确定”

    说明

    所键入的字符串随即显示在 SerializationDemoControlTextBox 中。

  6. 解决方案资源管理器中,单击 显示所有文件 按钮。

  7. 打开 Form1 节点。 其下方是一个名为 Form1.Designer.csForm1.Designer.vb的文件。 这是 Windows 窗体设计器向其中发出代码的文件,该代码表示窗体及其子控件的设计时状态。 在 代码编辑器中打开此文件。

  8. 打开名为“Windows 窗体设计器生成的代码”的区域,找到标有 serializationDemoControl1 的部分。 此标签下方是表示控件的序列化状态的代码。 在执行步骤 5 时输入的字符串出现在 Strings 属性的值分配中。 C# 和 Visual Basic 中的以下代码示例显示类似于键入字符串“red”、“orange”和“yellow”时将看到的代码。

    this.serializationDemoControl1.Strings = new string[] {
            "red",
            "orange",
            "yellow"};
    
    Me.serializationDemoControl1.Strings = New String() {"red", "orange", "yellow"}
    
  9. 代码编辑器中,将 Strings 属性上的 DesignerSerializationVisibilityAttribute 的值更改为 Hidden

    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    
    <DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
    
  10. 重新生成解决方案并重复步骤 3 和步骤 4。

说明

在这种情况下,Windows 窗体设计器 不会向 Strings 属性发出任何分配。

后续步骤

了解如何序列化标准类型的集合后,请考虑将自定义控件更深入地集成到设计时环境中。 以下主题介绍如何增强自定义控件的设计时集成:

另请参阅