C# Window form 自定义控件的结构和设计(三)
一、前面介绍了如何来创建第一个自定义的控件,以及一个测试程序。下面我们来看下如何在自定义控件中添加属性。
C#和其他.NET语言支持属性作为语言的第一类成员。把属性作为语言的基础属性有两点主要的有点:
①利用属性使放射返回一个类的属性更加简单。
②编写代码时,我们可以取得或者设置属性,就像取得或者设置一个类的成员变量一样。
接下来,我们来创建一个实现许多属性的自定义控件。
和之前的程序一样修改基类为System.Windows.Forms.Control。
第一步在类中添加属性值,如下所示:
public enum TextDirection{VerticalText,HorizonalText};// 字段名称要输出的文本private string displayText;// 文本被输出的次数private int displayCount;// 文本被显示的颜色private Color textColor;// 用来显示文本的字体private Font textFont;// 文本显示方向private TextDirection textDirection;// 文本显示位置private Point startDisplayPoint;// 属性实现public string DisplayText{get { return displayText; }set { displayText = value; Invalidate(); }}public int DisplayCount{get { return displayCount; }set { displayCount = value; Invalidate(); }}public Color TextColor{get { return textColor; }set { textColor = value; Invalidate(); }}public Font TextFont{get { return textFont; }set { textFont = value; Invalidate(); }}public TextDirection TextDirect{get { return textDirection; }set { textDirection = value; Invalidate(); }}public Point StartDisplayPoint{get { return startDisplayPoint; }set { startDisplayPoint = value; Invalidate(); }}
第二步然后添加一个控件Paint事件,代码如下:
Graphics g = e.Graphics;g.FillRectangle(Brushes.White, ClientRectangle);PointF point = StartDisplayPoint;Brush brush = new SolidBrush(textColor);StringFormat sf = new StringFormat();if (TextFont == null)TextFont = new Font("Times New Roman", 12);if (TextDirect == TextDirection.VerticalText)sf.FormatFlags = StringFormatFlags.DirectionVertical;for (int nCount = 0; nCount < displayCount; nCount++){g.DrawString(displayText, TextFont, brush, point.X, point.Y, sf);if (TextDirect == TextDirection.VerticalText)point.X += TextFont.GetHeight();elsepoint.Y += TextFont.GetHeight();}
运行程序,生成一个CustomControlWithProperties.dll。
接下来我们,我们生成一个测试程序,如下图:
在窗体编辑器中可以看到我们刚才生成的控件。拖放到窗体中,在右边的控件属性窗口中,我们看到了我们刚才自定义的控件属性值。
二、属性的默认值
在上面自定义控件代码中,所有的属性都是空白的。但是在很多情况下,我们需要把属性值设置为有意义的值。我们需要注意两个问题:
①确定属性是在控件代码中初始化的。
②确定VS编译器了解默认值。
在刚才的程序中,我们添加默认的属性值。代码如下:
private string displayText = "GoodBye,World";// 文本被输出的次数private int displayCount = 5;// 文本被显示的颜色private Color textColor = Color.Lime;// 用来显示文本的字体private Font textFont = new Font("Times New Roman", 12);// 文本显示方向private TextDirection textDirection = TextDirection.VerticalText;// 文本显示位置private Point startDisplayPoint = new Point(6, 6);
我们需要将默认值显示到VS的属性窗口中,有两种方式:
①在属性的声明前设置一个属性。
在DisplayText,DisplayCount,TextDirect属性中设置如下属性:
// 属性的实现[DefaultValue("Hello,World")]public string DisplayText{get { return displayText; }set { displayText = value; Invalidate(); }}[DefaultValue(3)]public int DisplayCount{get { return displayCount; }set { displayCount = value; Invalidate(); }}[DefaultValue(TextDirection.HorizonalText)]public TextDirection TextDirect{get { return textDirection; }set { textDirection = value; Invalidate(); }}
说明:当我们的属性值属于其值可以作为属性中一个参数的类型(一个字符串,一个数字,或者一个枚举)列出时,这种方式是很好的。
②我们使用一种基于Reset和ShouldSerialize的方法。使用这种方式,我们可以将属性重置为默认值。并将给定属性和默认值比较。更具体的说:Reset负责重置为默认属性。ShouldSerialize检查属性是否具有默认值。
public void ResetTextColor(){TextColor = Color.Red;}public bool ShouldSerializeTextColor(){return TextColor != Color.Red;}public void ResetTextFont(){TextFont = new Font("Times New Roman",12);}public bool ShouldSerializeTextFont(){return !TextFont.Equals(new Font("Times New Roman", 12));}public void ResetStartDisplayPoint(){StartDisplayPoint = new Point(6,6);}public bool ShouldSerializeStartDisplayPoint(){return StartDisplayPoint != new Point(6, 6);}
运行自定义控件程序,然后再测试程序中再次打开控件属性,可以看到右键菜单项中多了一个重置的功能。
运行自定义控件程序,然后再测试程序中再次打开控件属性,可以看到右键菜单项中多了一个重置的功能。
好了,自定义控件添加属性的功能就介绍到这里了。欢迎大家一起交流。