目的:
我们要明确控件属性为什么要串行化?
关于串行化的定义如果你还不熟悉的话可以Baidu下,简单的说就是,我们要将我们在控件属性上设定的值持久化到代码中,这样我们下次再查看控件的值依然是我们最后一次设定的值。
备注:
关于DesignerSerializationVisibilityAttribute的解释
指示一个属性是否串行化和如何串行化,它的值是一个枚举,一共有三种类型Content,Hidden,Visible。
Content 指示代码生成器为对象包含的内容生成代码,而不是为对象本身;
Hidden 指示代码生成器不为对象生成代码;
Visible 指示代码生成器为对象生成代码。
对不是集合类型的属性使用Content 标记会使设计器不生成属性的内容,会导致在设计界面设置该属性后保存无效的情况,对是集合类型的属性使用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();
最后我们看下效果: