WinForm控件开发和美化(2)——PanelEx控件

C# WinForm控件开发和美化(2)——PanelEx控件
今天介绍WinForm控件开发和美化系列的第一个控件Panel控件。这个控件本身比较简单,主要就是用到了一些GDI+的知识。作为这个系列的第一个控件,在这里也介绍一些控件开发和GDI+的内容。

在看过这篇系列文章后,如果您有什么好的意见和建议,请给我留言或者直接给我发邮件,我的邮箱地址是:381878765@https://www.360docs.net/doc/df5819792.html,。本人现在在云南省昆明市工作,欢迎志同道合的朋友和我一起交流。



一、效果图





二、实现代码

namespace Lt_WinControls

{


[DefaultProperty("Visible"), DefaultEvent("Click")]

[ToolboxItem(true)]

[ToolboxBitmap(typeof(PanelEx), "Resources.PanelEx.bmp")]

[Description("表示一个可以自定义边框样式的Panel控件。")]

//[Designer(typeof(PanelExDesigner))]

//[Docking(DockingBehavior.Ask)]

public class PanelEx : Panel

{

#region 属性

bool _topLeft = true;

[DefaultValue(true)]

[Description("当CornerMode为Round时,是否显示左上角"), Category("自定义外观")]

public bool TopLeft

{

get { return _topLeft; }

set

{

_topLeft = value;

base.Invalidate();

}

}



bool _topRight = true;

[DefaultValue(true)]

[Description("当CornerMode为Round时,是否显示右上角"), Category("自定义外观")]

public bool TopRight

{

get { return _topRight; }

set

{

_topRight = value;

base.Invalidate();

}

}



bool _bottomLeft = true;

[DefaultValue(true)]

[Description("当CornerMode为Round时,是否显示左下角"), Category("自定义外观")]

public bool BottomLeft

{

get { return _bottomLeft; }

set

{

_bottomLeft = value;

base.Invalidate();

}

}

bool _bottomRight = true;

[DefaultValue(true)]

[Description("当CornerMode为Round时,是否显示右下角"), Category("自定义外观")]

public bool BottomRight

{

get { return _bottomRight; }

set

{

_bottomRight = value;

base.Invalidate();

}

}



private Color _borderColor = Color.Black;

[DefaultValue(typeof(Color), "Black")]

[Description("设置边框线的颜色"), Category("自定义外观")]

public Color BorderColor

{

get { return _borderColor; }

set

{


_borderColor = value;

base.Invalidate();

}

}

private GradientMode _gradientMode = GradientMode.None;

[DefaultValue(typeof(GradientMode), "0")]

[Description("用渐变色来填充背景时的填充方式"), Category("自定义外观")]

public GradientMode GradientMode

{

get { return _gradientMode; }

set

{

_gradientMode = value;

base.Invalidate();

}

}

[Browsable(false)]

[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]

public override Color BackColor

{

get

{

return Color.Transparent;

}

}

private Color _backColor1 = Color.White;

[DefaultValue(typeof(Color), "White")]

[Description("控件的背景色1(若同时设置两个背景色,就是会用渐变色来填充背景)"), Category("自定义外观")]

public Color BackColor1

{

get { return _backColor1; }

set

{

_backColor1 = value;

base.Invalidate();

}

}

private Color _backColor2 = Color.White;

[DefaultValue(typeof(Color), "White")]

[Description("控件的背景色2,当GradientMode不为None时有效"), Category("自定义外观")]

public Color BackColor2

{

get { return _backColor2; }

set

{

_backColor2 = value;

base.Invalidate();

}

}

private int _borderWidth = 1;

[DefaultValue(1)]

[Description("设置边框线的宽度"), Category("自定义外观")]

public int BorderWidth

{

get { return _borderWidth; }

set

{

if (value >= 0)

{

_borderWidth = value;

SetPadding();

base.Invalidate();

}

}

}



private DashStyle _borderStyle = DashStyle.Solid;

[DefaultValue(typeof(DashStyle), "0")]

[Description("设置边框线样式"), Category("自定义外观")]

public new DashStyle BorderStyle

{

get { return _borderStyle; }

set

{

_borderStyle = value;

base.Invalidate();

}

}



private int _roundSize = 15;

///



/// 设置边角大小

///


[DefaultValue(15)]

[Description("当CornerMode为Round时,设置边角大小"), Category("自定义

外观")]

public int RoundSize

{

get { return _roundSize; }

set

{

if (value > 0)

{

_roundSize = value;

base.Invalidate();

}

}

}



private CornerMode _cornerMode = CornerMode.Corner;

///



/// 设置边角样式

///


[DefaultValue(typeof(CornerMode), "2")]

[Description("设置边角样式"), Category("自定义外观")]

public CornerMode CornerMode

{

get { return _cornerMode; }

set

{

_cornerMode = value;

SetPadding();

base.Invalidate();

}

}



private bool _leftBorder = true;

///

/// 左边框是否显示

///


[DefaultValue(true)]

[Description("当CornerMode为Corner时,是否显示左边框"), Category("自定义外观")]

public bool LeftBorder

{

get { return _leftBorder; }

set

{

_leftBorder = value;

base.Invalidate();

}

}



private bool _rightBorder = true;

///

/// 是否显示右边框

///


[DefaultValue(true)]

[Description("当CornerMode为Corner时,是否显示右边框"), Category("自定义外观")]

public bool RightBorder

{

get { return _rightBorder; }

set

{

_rightBorder = value;

base.Invalidate();

}

}



private bool _topBorder = true;

///

/// 是否显示上边框

///


[DefaultValue(true)]

[Description("当CornerMode为Corner时,是否显示上边框"), Category("自定义外观")]

public bool TopBorder

{

get { return _topBorder; }

set

{

_topBorder = value;

base.Invalidate();

}

}



private bool _bottomBorder = true;

///

/// 是否显示下边框

///


[DefaultValue(true)]

[Description("当CornerMode为Corner时,是否显示下边框"), Category("自定义外观")]

public bool BottomBorder

{

get { return _bottomBorder; }

set

{

_bottomBorder = value;

base.Invalidate();

}

}

#endregion



#region 构造函数

///

ummary>

/// 构造函数

///

public PanelEx()

{

base.ResizeRedraw = true;

this.BackColor = Color.Transparent;

}

#endregion



private void SetPadding()

{

int left = this.Padding.Left;

int right = this.Padding.Right;

int top = this.Padding.Top;

int bottom = this.Padding.Bottom;

if (this.CornerMode == CornerMode.None)

{

left = 0;

right = 0;

top = 0;

bottom = 0;

}

else

{

if (this.Padding.Left < this.BorderWidth)

{

left = this.BorderWidth;

}

if (this.Padding.Right < this.BorderWidth)

{

right = this.BorderWidth;

}

if (this.Padding.Top < this.BorderWidth)

{

top = this.BorderWidth;

}

if (this.Padding.Bottom < this.BorderWidth)

{

bottom = this.BorderWidth;

}

}

this.Padding = new Padding(left, top, right, bottom);

}



#region 控件重绘事件

///



/// 控件重绘事件

///


///

protected override void OnPaint(PaintEventArgs e)

{

base.OnPaint(e);

Graphics g = e.Graphics;

g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

Rectangle rec = new Rectangle(0, 0, this.Width, this.Height);

Pen pen = new Pen(BorderColor, BorderWidth);

pen.DashStyle = BorderStyle;

GraphicsPath path = CreateRound(rec, RoundSize, this.TopLeft, this.TopRight, this.BottomLeft, this.BottomRight);



//绘制背景

if (this.GradientMode == GradientMode.None)

{

using (Brush brush2 = new SolidBrush(this.BackColor1))

{

if (this.CornerMode == CornerMode.Round)

{

g.FillPath(brush2, path);

}

else

{

g.FillRectangle(brush2, rec);

}

}

}

else

{

if (this.CornerMode == CornerMode.Round)

{

DrawGradient(g, rec, path, this.BackColor1, this.BackColor2, this._gradientMode);

}

else

{

DrawGradient(g,

rec, this.BackColor1, this.BackColor2, this._gradientMode);

}

}



//绘制边框

if (BorderWidth > 0)

{

switch (CornerMode)

{

case CornerMode.None:

break;

case CornerMode.Corner:

if (LeftBorder)

{

g.DrawLine(pen, 0, 0, 0, this.Height - 1);

}

if (BottomBorder)

{

g.DrawLine(pen, 0, this.Height - 1, this.Width - 1, this.Height - 1);

}

if (RightBorder)

{

g.DrawLine(pen, Width - 1, this.Height - 1, this.Width - 1, 0);

}

if (TopBorder)

{

g.DrawLine(pen, this.Width - 1, 0, 0, 0);

}

break;

case CornerMode.Round:

g.DrawPath(pen, path);

break;

}

}

}

#endregion



public static GraphicsPath CreateRound(Rectangle rect, int radius, bool topLeft, bool topRight, bool bottomLeft, bool bottomRight)

{

rect.Width -= 1;

rect.Height -= 1;



GraphicsPath roundRect = new GraphicsPath();

//顶端

roundRect.AddLine(rect.Left + radius / 2, rect.Top, rect.Right - radius / 2, rect.Top);

//右上角

if (topRight)

{

roundRect.AddArc(rect.Right - radius, rect.Top, radius, radius, 270, 90);

}

else

{

roundRect.AddLine(rect.Right - radius / 2, rect.Top, rect.Right, rect.Top);

roundRect.AddLine(rect.Right, rect.Top, rect.Right, rect.Top + radius / 2);

}



//右边

roundRect.AddLine(rect.Right, rect.Top + radius / 2, rect.Right, rect.Bottom - radius / 2);



//右下角

if (bottomRight)

{

roundRect.AddArc(rect.Right - radius, rect.Bottom - radius, radius, radius, 0, 90);

}

else

{

roundRect.AddLine(rect.Right, rect.Bottom - radius / 2, rect.Right, rect.Bottom);

roundRect.AddLine(rect.Right, rect.Bottom, rect.Right - radius / 2, rect.Bottom);

}



//底边

roundRect.AddLine(rect.Right - radius / 2, rect.Bottom, rect.Left + radius / 2, rect.Bottom);



//左下角

if (bottomLeft)



{

roundRect.AddArc(rect.Left, rect.Bottom - radius, radius, radius, 90, 90);

}

else

{

roundRect.AddLine(rect.Left + radius / 2, rect.Bottom, rect.Left, rect.Bottom);

roundRect.AddLine(rect.Left, rect.Bottom, rect.Left, rect.Bottom - radius / 2);

}



//左边 不需要了

// roundRect.AddLine(rect.Left, rect.Top + radius / 2, rect.Left, rect.Bottom - radius / 2);



//左上角

if (topLeft)

{

roundRect.AddArc(rect.Left, rect.Top, radius, radius, 180, 90);

}

else

{

roundRect.AddLine(rect.Left, rect.Top + radius / 2, rect.Left, rect.Top);

roundRect.AddLine(rect.Left, rect.Top, rect.Left + radius / 2, rect.Top);

}

//闭合图像

roundRect.CloseAllFigures();

return roundRect;

}





public static void DrawGradient(Graphics e, Rectangle rect, GraphicsPath path, Color color1, Color color2, GradientMode mode)

{

LinearGradientMode backwardDiagonal = LinearGradientMode.BackwardDiagonal;

if (mode == GradientMode.Vertical)

{

backwardDiagonal = LinearGradientMode.Vertical;

}

else if (mode == GradientMode.Horizontal)

{

backwardDiagonal = LinearGradientMode.Horizontal;

}

else if (mode == GradientMode.BackwardDiagonal)

{

backwardDiagonal = LinearGradientMode.BackwardDiagonal;

}

else if (mode == GradientMode.ForwardDiagonal)

{

backwardDiagonal = LinearGradientMode.ForwardDiagonal;

}

LinearGradientBrush brush = new LinearGradientBrush(rect, color1, color2, backwardDiagonal);

e.FillPath(brush, path);

brush.Dispose();

}



public static void DrawGradient(Graphics e, Rectangle rect, Color color1, Color color2, GradientMode mode)

{

LinearGradientMode backwardDiagonal = LinearGradientMode.BackwardDiagonal;

if (mode == GradientMode.Vertical)

{

backwardDiagonal = LinearGradientMode.Vertical;

}

else if (mode == GradientMode.Horizontal)

{

backwardDiagonal = LinearGradientMode.Horizontal;

}

else if (mode == GradientMode.BackwardDiagonal)

{

backwardDiagonal = LinearGradientMode.BackwardDiagonal;

}

else if (mode == GradientMode.ForwardDiagonal)

{

backwardDiagonal = LinearGra

dientMode.ForwardDiagonal;

}

LinearGradientBrush brush = new LinearGradientBrush(rect, color1, color2, backwardDiagonal);

e.FillRectangle(brush, rect);

brush.Dispose();

}

}





public enum GradientMode

{

///



/// 无填充样式

///


None = 0,

///

/// 垂直填充

///


Vertical = 1,

///

/// 水平填充

///


Horizontal = 2,

///

/// 右上角到左下角

///


BackwardDiagonal = 3,

///

/// 左上角到右下角

///


ForwardDiagonal = 4

}



public enum CornerMode

{

///

/// 没有边框

///


None = 0,



///

/// 指定圆角

/// 此时的边框设置以上边框为准

///


Round = 1,



///

/// 指定尖角

///


Corner = 2,

}

}

三、控件设计知识介绍

1、类的属性集



定义控件的默认属性和默认事件:

设置默认属性后,在设计时选中该控件的话,属性栏中的默认属性会变成灰色;

设置默认事件后,在设计时双击该控件会自动生成默认的事件代码,比如双击这个控件后会生成Click事件的代码

//[DefaultProperty("Visible"), DefaultEvent("Click")]

下面这个属性设置这个控件是否在控件工具箱中显示

[ToolboxItem(true)]

下面这个属性设置这个控件显示在工具箱中的图标,可以设置成自己定义的图标

[ToolboxBitmap(typeof(PanelEx), "Resources.PanelEx.bmp")]

下面的属性设置在工具箱中显示的控件的提示内容

[Description("表示一个可以自定义边框样式的Panel控件。")]


下面的属性设置控件的设计类,就是在设置时显示在控件右上角的小三角里面的内容,panle控件设置了设计类比较奇怪,无法当做容器来使用。

所以在这里就不介绍控件的设计类了,这部分放到后面的控件来介绍

//[Designer(typeof(PanelExDesigner))]

下面是属性设置控件默认的停靠属性,Ask表示有用户来设置停靠方式

//[Docking(DockingBehavior.Ask)]

public class PanelEx : Panel

{

}

2、属性的属性集

即使设置了默认值,在声明字段的时候或构造函数里面还是要对字段进行赋值,不然默认值的设置就没有意义了

private Color _backColor1 = Color.White;

设置属性的默认值,这个地

方给很多人造成了误解,认为设置了默认属性值,在代码生成的时候就自动生成默认的值了,

其实不是这样,设置默认值有两个作用:

一是如果设置的值和默认值相同的话,在控件的属性列表中就不会加粗显示这个值;

而是如果设置的值和默认值相同的话,在控件的生成过程中不生成对该属性的赋值代码(这一点很关键)。

[DefaultValue(typeof(Color), "White")]

下面的属性设置这个属性在控件的属性窗口中的分类和提示信息

[Description("控件的背景色1(若同时设置两个背景色,就是会用渐变色来填充背景)"), Category("自定义外观")]

public Color BackColor1

{

get { return _backColor1; }

set

{

_backColor1 = value;

base.Invalidate();

}

}

由于在自定义控件中,已经设置了控件的背景色,并且我希望控件原来的背景色一直是透明的,所以用下面的方法来屏蔽控件本身的属性BackColor

这个属性设置控件的该属性不显示在在控件的属性窗口中

[Browsable(false)]

表示在控件生成的时候不生成这个属性的代码

[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]

public override Color BackColor

{

get

{

让属性的值一直返回透明色,这样你即使在客户端代码中设置了这个属性,也是无效的

return Color.Transparent;

}

}

在这里我只介绍这个项目中用到的一些内容,还有一些内容会在以后用到的时候在给大家介绍。

比如: 一些属性本身就是一个类,这个类本身也包含很多的属性,我们希望在代码生成的时候不生成这个类本身的代码,而是希望生成这个类的子属性的代码。

并且在属性窗口中看到的也是这个类的子属性,这些都会在后面的内容介绍。


相关主题
相关文档
最新文档