winform中的TextBox控件没有Radius属性,无法设置文本款为圆角。然后就想自己写一个自定义的圆角控件。一开始想,既然要写那就从头开始写,于是就开始写了起来。刚开始一切都很顺利,等我把界面画完之后,老天跟我开了一个大玩笑,我发现直接从Control类继承写不下去了,太复杂我要去研究一下源码,然后发现源码中的TextBox是一个mfc控件。好吧,这么麻烦,算了。换个思路,后来我就想我只需要画个带弧度的框然后再在里面放一个TextBox这不就实现了吗?想到就做,没想到还真的成功了。下面是我的源码。
public partial class FengTextBoxEx : Control
{
TextBox textBox = new TextBox();
public override string Text
{
get
{
return textBox.Text;
}
set
{
textBox.Text = value;
}
}
private Color borderColor = Color.Black;
///
/// 边框颜色
///
public Color BorderColor
{
get
{
return this.borderColor;
}
set
{
this.borderColor = value;
}
}
private int borderThickness = 1;
///
/// 边框粗细
///
public int BorderThickness
{
get
{
return this.borderThickness;
}
set
{
this.borderThickness = value;
}
}
private int borderRadius = 0;
///
/// 边框半径
///
public int BorderRadius
{
get
{
return this.borderRadius;
}
set
{
this.borderRadius = value;
}
}
public FengTextBoxEx()
{
InitializeComponent();
this.SetStyle(ControlStyles.DoubleBuffer |
ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.SupportsTransparentBackColor,
true);
this.UpdateStyles();
textBox.BorderStyle = BorderStyle.None;
this.Controls.Add(textBox);
}
protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
{
height = textBox.Height + borderThickness * 2 + 2;
base.SetBoundsCore(x, y, width, height, specified);
}
protected override void OnPaintBackground(PaintEventArgs pevent)
{
pevent.Graphics.Clear(Parent.BackColor);
if (Color.Transparent.ToArgb() == BackColor.ToArgb())
textBox.BackColor = Color.White;
else
textBox.BackColor = BackColor;
textBox.ForeColor = ForeColor;
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
Graphics g = pe.Graphics;
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.CompositingQuality = CompositingQuality.HighQuality;
if (borderThickness <= 0)
return;
Pen pen = new Pen(borderColor, borderThickness);
if (borderRadius <= 0)
{
g.DrawRectangle(pen, 0, 0, this.Width - 1, this.Height - 1);
g.FillRectangle(new SolidBrush(BackColor), 0, 0, this.Width - 1, this.Height - 1);
return;
}
// 要实现 圆角化的 矩形
Rectangle rect = new Rectangle(0, 0, this.Width - 1, this.Height - 1);
// 指定图形路径, 有一系列 直线/曲线 组成
GraphicsPath borderPath = new GraphicsPath();
borderPath.StartFigure();
borderPath.AddArc(new Rectangle(new Point(rect.X, rect.Y), new Size(2 * borderRadius, 2 * borderRadius)), 180, 90);
borderPath.AddLine(new Point(rect.X + borderRadius, rect.Y), new Point(rect.Right - borderRadius, rect.Y));
borderPath.AddArc(new Rectangle(new Point(rect.Right - 2 * borderRadius, rect.Y), new Size(2 * borderRadius, 2 * borderRadius)), 270, 90);
borderPath.AddLine(new Point(rect.Right, rect.Y + borderRadius), new Point(rect.Right, rect.Bottom - borderRadius));
borderPath.AddArc(new Rectangle(new Point(rect.Right - 2 * borderRadius, rect.Bottom - 2 * borderRadius), new Size(2 * borderRadius, 2 * borderRadius)), 0, 90);
borderPath.AddLine(new Point(rect.Right - borderRadius, rect.Bottom), new Point(rect.X + borderRadius, rect.Bottom));
borderPath.AddArc(new Rectangle(new Point(rect.X, rect.Bottom - 2 * borderRadius), new Size(2 * borderRadius, 2 * borderRadius)), 90, 90);
borderPath.AddLine(new Point(rect.X, rect.Bottom - borderRadius), new Point(rect.X, rect.Y + borderRadius));
borderPath.CloseFigure();
g.DrawPath(pen, borderPath);
g.FillPath(new SolidBrush(BackColor), borderPath);
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
int y = Height - textBox.Height - borderThickness;
textBox.Location = new Point(borderThickness + borderRadius, y);
textBox.Size = new Size(this.Width - borderThickness * 2 - borderRadius * 2, this.Height - borderThickness);
}
}
这个只是一个初步的代码,应该还有优化的空间,后面等我优化完了,再放上来,效果如下:
放上来希望可以帮助那些,和我一样需要的人。我看csdn上也有这样的带圆角的TextBox源码,不过都要积分才能下载。也不知道他们是怎么实现的。