【WinForm窗体控件开发】之四 DesignerSerializationVisibilityAttribute 控件属性的串行化

这次我们来说说控件属性的串行化。

目的:


我们要明确控件属性为什么要串行化?

关于串行化的定义如果你还不熟悉的话可以Baidu下,简单的说就是,我们要将我们在控件属性上设定的值持久化到代码中,这样我们下次再查看控件的值依然是我们最后一次设定的值。

备注:


关于DesignerSerializationVisibilityAttribute的解释

  指示一个属性是否串行化和如何串行化,它的值是一个枚举,一共有三种类型ContentHiddenVisible

  Content 指示代码生成器为对象包含的内容生成代码,而不是为对象本身;

  Hidden   指示代码生成器不为对象生成代码;

  Visible    指示代码生成器为对象生成代码。

1.假如你的控件有一个集合属性,又想在设计时自动将集合属性的内容生成代码,那么就使用这个Attribute,并将值设为DesignerSerializationVisibility.Content

2.没有DesignerSerializationVisibilityAttribute的成员将被视为具有值为 Visible 的 DesignerSerializationVisibilityAttribute,如果可能,序列化程序会将标记为 Visible 的属性 (Property) 值序列化为该类型;

 

下面我来看下窗体控件的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WinFormControlLibrary
{
public partial class ThirdControl自定义控件属性的串行化 : Control
{
#region Field
/// <summary>
/// 名
/// </summary>
private String _firstName = "Bobby";
/// <summary>
/// 姓
/// </summary>
private String _lastName = "Chen";

/// <summary>
/// 集合1
/// </summary>
private List<Int32> _collection1 = new List<Int32>();
/// <summary>
/// 集合2
/// </summary>
private List<Int32> _collection2 = new List<Int32>();

[BrowsableAttribute(true)]
// 若不设置,则默认为 [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public List<Int32> Collection1
{
get { return _collection1; }
set { _collection1 = value; }
}

[BrowsableAttribute(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public List<Int32> Collection2
{
get { return _collection2; }
set { _collection2 = value; }
}

[
BrowsableAttribute(true),
BindableAttribute(false),
CategoryAttribute("自定义项目"),
DescriptionAttribute("名"),
]
public String FirstName
{
get { return _firstName; }
set { _firstName = value; }
}

[
BrowsableAttribute(true),
BindableAttribute(false),
CategoryAttribute("自定义项目"),
DescriptionAttribute("姓"),
]
public String LastName
{
get { return _lastName; }
set { _lastName = value; }
}
#endregion

public ThirdControl自定义控件属性的串行化()
{
InitializeComponent();
}

protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);

#region 重绘控件
Graphics g = pe.Graphics;

//
// 设定大小区域
//
Size size = new Size(Size.Width - 1, Size.Height - 1);
//
// 设定Control 的大小
//
Rectangle rectagle = new Rectangle(Point.Empty, size);

// 绘制控件边框
g.DrawRectangle(Pens.Black, rectagle);

// 绘制控件内容
for (Int32 i = 0; i < _collection1.Count; i++)
{
g.DrawString(_collection1[i].ToString(), Font, Brushes.Red, 1, i * FontHeight);
}

for (Int32 i = 0; i < _collection2.Count; i++)
{
g.DrawString(_collection2[i].ToString(), Font, Brushes.Red, 10, i * FontHeight);
}
#endregion
}
}
}

在这个控件中,我们定义了两个泛型集合Collection1 和 Collection2 。

Collection1默认没有使用DesignerSerializationVisibilityAttribute属性,因此会默认提供为控件指定DesignerSerializationVisibilityAttribute.Visible值;

Collection2则指定了DesignerSerializationVisibilityAttribute.Content值;

 

我们将控件添加到一个窗体中,并为Collection1赋值 1,2,3,4,为Collection2赋值 5,6,7,8

下面我们来看一下这个控件在窗体中的代码:

namespace 自定义窗体控件Demo
{
partial class 之四窗体控件实现属性的串行化
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;

/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}

#region Windows Form Designer generated code

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(之四窗体控件实现属性的串行化));
this.thirdControl自定义控件属性的串行化1 = new WinFormControlLibrary.ThirdControl自定义控件属性的串行化();
this.SuspendLayout();
//
// thirdControl自定义控件属性的串行化1
//
this.thirdControl自定义控件属性的串行化1.Collection1 = ((System.Collections.Generic.List<int>)(resources.GetObject("thirdControl自定义控件属性的串行化1.Collection1")));
this.thirdControl自定义控件属性的串行化1.Collection2.Add(4);
this.thirdControl自定义控件属性的串行化1.Collection2.Add(5);
this.thirdControl自定义控件属性的串行化1.Collection2.Add(6);
this.thirdControl自定义控件属性的串行化1.Collection2.Add(7);
this.thirdControl自定义控件属性的串行化1.FirstName = "Bobby";
this.thirdControl自定义控件属性的串行化1.LastName = "Chen";
this.thirdControl自定义控件属性的串行化1.Location = new System.Drawing.Point(30, 12);
this.thirdControl自定义控件属性的串行化1.Name = "thirdControl自定义控件属性的串行化1";
this.thirdControl自定义控件属性的串行化1.Size = new System.Drawing.Size(133, 93);
this.thirdControl自定义控件属性的串行化1.TabIndex = 0;
this.thirdControl自定义控件属性的串行化1.Text = "thirdControl自定义控件属性的串行化1";
//
// 之四窗体控件实现属性的串行化
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(297, 262);
this.Controls.Add(this.thirdControl自定义控件属性的串行化1);
this.Name = "之四窗体控件实现属性的串行化";
this.Text = "之四窗体控件实现属性的串行化";
this.ResumeLayout(false);

}

#endregion

private WinFormControlLibrary.ThirdControl自定义控件属性的串行化 thirdControl自定义控件属性的串行化1;
}
}
em.ComponentModel.IContainer components = null;

/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}

#region Windows Form Designer generated code

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(之四窗体控件实现属性的串行化));
this.thirdControl自定义控件属性的串行化1 = new WinFormControlLibrary.ThirdControl自定义控件属性的串行化();
this.SuspendLayout();
//
// thirdControl自定义控件属性的串行化1
//
this.thirdControl自定义控件属性的串行化1.Collection1 = ((System.Collections.Generic.List<int>)(resources.GetObject("thirdControl自定义控件属性的串行化1.Collection1")));
this.thirdControl自定义控件属性的串行化1.Collection2.Add(4);
this.thirdControl自定义控件属性的串行化1.Collection2.Add(5);
this.thirdControl自定义控件属性的串行化1.Collection2.Add(6);
this.thirdControl自定义控件属性的串行化1.Collection2.Add(7);
this.thirdControl自定义控件属性的串行化1.FirstName = "Bobby";
this.thirdControl自定义控件属性的串行化1.LastName = "Chen";
this.thirdControl自定义控件属性的串行化1.Location = new System.Drawing.Point(30, 12);
this.thirdControl自定义控件属性的串行化1.Name = "thirdControl自定义控件属性的串行化1";
this.thirdControl自定义控件属性的串行化1.Size = new System.Drawing.Size(133, 93);
this.thirdControl自定义控件属性的串行化1.TabIndex = 0;
this.thirdControl自定义控件属性的串行化1.Text = "thirdControl自定义控件属性的串行化1";
//
// 之四窗体控件实现属性的串行化
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(297, 262);
this.Controls.Add(this.thirdControl自定义控件属性的串行化1);
this.Name = "之四窗体控件实现属性的串行化";
this.Text = "之四窗体控件实现属性的串行化";
this.ResumeLayout(false);

}

#endregion

private WinFormControlLibrary.ThirdControl自定义控件属性的串行化 thirdControl自定义控件属性的串行化1;
}
}

 

我们重点看一下 thirdControl自定义控件属性的串行化1 这个代码,我把它单独列出来,如下:

// 
// thirdControl自定义控件属性的串行化1
//
this.thirdControl自定义控件属性的串行化1.Collection1 = ((System.Collections.Generic.List<int>)(resources.GetObject("thirdControl自定义控件属性的串行化1.Collection1")));
this.thirdControl自定义控件属性的串行化1.Collection2.Add(4);
this.thirdControl自定义控件属性的串行化1.Collection2.Add(5);
this.thirdControl自定义控件属性的串行化1.Collection2.Add(6);
this.thirdControl自定义控件属性的串行化1.Collection2.Add(7);
this.thirdControl自定义控件属性的串行化1.FirstName = "Bobby";
this.thirdControl自定义控件属性的串行化1.LastName = "Chen";
this.thirdControl自定义控件属性的串行化1.Location = new System.Drawing.Point(30, 12);
this.thirdControl自定义控件属性的串行化1.Name = "thirdControl自定义控件属性的串行化1";
this.thirdControl自定义控件属性的串行化1.Size = new System.Drawing.Size(133, 93);
this.thirdControl自定义控件属性的串行化1.TabIndex = 0;
this.thirdControl自定义控件属性的串行化1.Text = "thirdControl自定义控件属性的串行化1";

 

Collection1中添加的数值(1,2,3,4)没有在窗体的Designer中生成代码,其实他被编译到窗体的资源文件中去了;

Collection2中的数值我们可以清楚的看见,因为使用了DesignerSerializationVisibilityAttribute.Content 所以指定的在窗体的Designer中自动产生了代码;

我们再来看看窗体中是怎样调用资源文件的:

System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(之四窗体控件实现属性的串行化));
this.thirdControl自定义控件属性的串行化1 = new WinFormControlLibrary.ThirdControl自定义控件属性的串行化();
this.SuspendLayout();

最后我们看下效果:

好了,基本上如何使用DesignerSerializationVisibilityAttribute属性就是这些内容了。

做到这里有肯能有人要问如果得的Collection是一个自定义类型,我要如何在窗体中进行设置呢,下一次我们讲TypeConverterAttribute类型转换属性将解决这个问题。

posted @ 2010-12-02 16:41  bobbychen  阅读(6677)  评论(0编辑  收藏  举报