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();
else
point.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);
}
运行自定义控件程序,然后再测试程序中再次打开控件属性,可以看到右键菜单项中多了一个重置的功能。
运行自定义控件程序,然后再测试程序中再次打开控件属性,可以看到右键菜单项中多了一个重置的功能。
好了,自定义控件添加属性的功能就介绍到这里了。欢迎大家一起交流。