C# 自定义重绘TextBox

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.ComponentModel; namespace ControlExs.ControlExs.TextBoxEx
{
public class QCTextBox : TextBox
{
#region Field private QQControlState _state = QQControlState.Normal;
private Font _defaultFont = new Font("微软雅黑", ); //当Text属性为空时编辑框内出现的提示文本
private string _emptyTextTip;
private Color _emptyTextTipColor = Color.DarkGray; #endregion #region Constructor public QCTextBox()
{
SetStyles();
this.Font = _defaultFont;
//this.AutoSize = true;
this.BorderStyle = BorderStyle.None;
} #endregion #region Properites [Description("当Text属性为空时编辑框内出现的提示文本")]
public String EmptyTextTip
{
get { return _emptyTextTip; }
set
{
if (_emptyTextTip != value)
{
_emptyTextTip = value;
base.Invalidate();
}
}
} [Description("获取或设置EmptyTextTip的颜色")]
public Color EmptyTextTipColor
{
get { return _emptyTextTipColor; }
set
{
if (_emptyTextTipColor != value)
{
_emptyTextTipColor = value;
base.Invalidate();
}
}
} private int _radius = ;
[Description("获取或设置圆角弧度")]
public int Radius
{
get { return _radius; }
set {
_radius = value;
this.Invalidate();
}
} [Description("获取或设置是否可自定义改变大小")]
public bool CustomAutoSize
{
get { return this.AutoSize; }
set { this.AutoSize = value; }
} #endregion #region Override protected override void OnMouseEnter(EventArgs e)
{
_state = QQControlState.Highlight;
base.OnMouseEnter(e);
} protected override void OnMouseLeave(EventArgs e)
{
if (_state == QQControlState.Highlight && Focused)
{
_state = QQControlState.Focus;
}
else if (_state == QQControlState.Focus)
{
_state = QQControlState.Focus;
}
else
{
_state = QQControlState.Normal;
}
base.OnMouseLeave(e);
} protected override void OnMouseDown(MouseEventArgs mevent)
{
if (mevent.Button == MouseButtons.Left)
{
_state = QQControlState.Highlight;
}
base.OnMouseDown(mevent);
} protected override void OnMouseUp(MouseEventArgs mevent)
{
if (mevent.Button == MouseButtons.Left)
{
if (ClientRectangle.Contains(mevent.Location))
{
_state = QQControlState.Highlight;
}
else
{
_state = QQControlState.Focus;
}
}
base.OnMouseUp(mevent);
} protected override void OnLostFocus(EventArgs e)
{
_state = QQControlState.Normal;
base.OnLostFocus(e);
} protected override void OnEnabledChanged(EventArgs e)
{
if (Enabled)
{
_state = QQControlState.Normal;
}
else
{
_state = QQControlState.Disabled;
}
base.OnEnabledChanged(e);
} protected override void WndProc(ref Message m)
{//TextBox是由系统进程绘制,重载OnPaint方法将不起作用 base.WndProc(ref m);
if (m.Msg == Win32.WM_PAINT || m.Msg == Win32.WM_CTLCOLOREDIT)
{
WmPaint(ref m);
}
} protected override void Dispose(bool disposing)
{
if (disposing)
{
if (_defaultFont != null)
{
_defaultFont.Dispose();
}
} _defaultFont = null;
base.Dispose(disposing);
} #endregion #region Private private void SetStyles()
{
// TextBox由系统绘制,不能设置 ControlStyles.UserPaint样式
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
UpdateStyles();
} private void WmPaint(ref Message m)
{
Graphics g = Graphics.FromHwnd(base.Handle); //g.SmoothingMode = SmoothingMode.AntiAlias;
//去掉 TextBox 四个角
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.AntiAlias;
SetWindowRegion(this.Width, this.Height); if (!Enabled)
{
_state = QQControlState.Disabled;
} switch (_state)
{
case QQControlState.Normal:
DrawNormalTextBox(g);
break;
case QQControlState.Highlight:
DrawHighLightTextBox(g);
break;
case QQControlState.Focus:
DrawFocusTextBox(g);
break;
case QQControlState.Disabled:
DrawDisabledTextBox(g);
break;
default:
break;
} if (Text.Length == && !string.IsNullOrEmpty(EmptyTextTip) && !Focused)
{
TextRenderer.DrawText(g, EmptyTextTip, Font, ClientRectangle, EmptyTextTipColor, GetTextFormatFlags(TextAlign, RightToLeft == RightToLeft.Yes));
}
} private void DrawNormalTextBox(Graphics g)
{
using (Pen borderPen = new Pen(Color.LightGray))
{
//g.DrawRectangle(borderPen, new Rectangle(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width - 1, ClientRectangle.Height - 1));
g.DrawPath(borderPen, DrawHelper.DrawRoundRect(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width - , ClientRectangle.Height - , _radius));
}
} private void DrawHighLightTextBox(Graphics g)
{
using (Pen highLightPen = new Pen(ColorTable.QQHighLightColor))
{
//Rectangle drawRect = new Rectangle(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width - 1, ClientRectangle.Height - 1);
//g.DrawRectangle(highLightPen, drawRect); g.DrawPath(highLightPen, DrawHelper.DrawRoundRect(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width - , ClientRectangle.Height - , _radius)); //InnerRect
//drawRect.Inflate(-1, -1);
//highLightPen.Color = ColorTable.QQHighLightInnerColor;
//g.DrawRectangle(highLightPen, drawRect); g.DrawPath(new Pen(ColorTable.QQHighLightInnerColor), DrawHelper.DrawRoundRect(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width - , ClientRectangle.Height - , _radius));
}
} private void DrawFocusTextBox(Graphics g)
{
using (Pen focusedBorderPen = new Pen(ColorTable.QQHighLightInnerColor))
{
//g.DrawRectangle(focusedBorderPen,new Rectangle(ClientRectangle.X,ClientRectangle.Y,ClientRectangle.Width - 1, ClientRectangle.Height - 1));
g.DrawPath(focusedBorderPen, DrawHelper.DrawRoundRect(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width - , ClientRectangle.Height - , _radius));
}
} private void DrawDownTextBox(Graphics g)
{
using (Pen focusedBorderPen = new Pen(ColorTable.QQHighLightInnerColor))
{
//g.DrawRectangle(focusedBorderPen,new Rectangle(ClientRectangle.X,ClientRectangle.Y,ClientRectangle.Width - 1, ClientRectangle.Height - 1));
g.DrawPath(focusedBorderPen, DrawHelper.DrawRoundRect(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width - , ClientRectangle.Height - , _radius));
}
} private void DrawDisabledTextBox(Graphics g)
{
using (Pen disabledPen = new Pen(SystemColors.ControlDark))
{
//g.DrawRectangle(disabledPen,new Rectangle( ClientRectangle.X,ClientRectangle.Y, ClientRectangle.Width - 1,ClientRectangle.Height - 1));
g.DrawPath(disabledPen, DrawHelper.DrawRoundRect(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width - , ClientRectangle.Height - , _radius));
}
} private static TextFormatFlags GetTextFormatFlags(HorizontalAlignment alignment, bool rightToleft)
{
TextFormatFlags flags = TextFormatFlags.WordBreak |
TextFormatFlags.SingleLine;
if (rightToleft)
{
flags |= TextFormatFlags.RightToLeft | TextFormatFlags.Right;
} switch (alignment)
{
case HorizontalAlignment.Center:
flags |= TextFormatFlags.VerticalCenter | TextFormatFlags.HorizontalCenter;
break;
case HorizontalAlignment.Left:
flags |= TextFormatFlags.VerticalCenter | TextFormatFlags.Left;
break;
case HorizontalAlignment.Right:
flags |= TextFormatFlags.VerticalCenter | TextFormatFlags.Right;
break;
}
return flags;
} #endregion public void SetWindowRegion(int width, int height)
{
System.Drawing.Drawing2D.GraphicsPath FormPath = new System.Drawing.Drawing2D.GraphicsPath();
Rectangle rect = new Rectangle(, , width, height);
FormPath = GetRoundedRectPath(rect, _radius);
this.Region = new Region(FormPath);
} private GraphicsPath GetRoundedRectPath(Rectangle rect, int radius)
{
int diameter = radius;
Rectangle arcRect = new Rectangle(rect.Location, new Size(diameter, diameter));
GraphicsPath path = new GraphicsPath();
// 左上角
path.AddArc(arcRect, , );
// 右上角
arcRect.X = rect.Right - diameter;
path.AddArc(arcRect, , );
// 右下角
arcRect.Y = rect.Bottom - diameter;
path.AddArc(arcRect, , );
// 左下角
arcRect.X = rect.Left;
path.AddArc(arcRect, , );
path.CloseFigure();
return path;
}
}
}
 public enum QQControlState
{
/// <summary>
/// 正常状态
/// </summary>
Normal = ,
/// <summary>
/// /鼠标进入
/// </summary>
Highlight = ,
/// <summary>
/// 鼠标按下
/// </summary>
Down = ,
/// <summary>
/// 获得焦点
/// </summary>
Focus = ,
/// <summary>
/// 控件禁止
/// </summary>
Disabled =
}
/// <summary>
/// 实现仿QQ效果控件内部使用颜色表
/// </summary>
internal class ColorTable
{
public static Color QQBorderColor = Color.LightBlue; //LightBlue = Color.FromArgb(173, 216, 230)
public static Color QQHighLightColor =RenderHelper.GetColor(QQBorderColor,,-,-,); //Color.FromArgb(110, 205, 253)
public static Color QQHighLightInnerColor = RenderHelper.GetColor(QQBorderColor, , -, -, ); //Color.FromArgb(73, 172, 231);
}
internal class DrawHelper
{
public static GraphicsPath DrawRoundRect(int x, int y, int width, int height, int radius)
{
GraphicsPath gp = new GraphicsPath();
gp.AddArc(x, y, radius, radius, , );
gp.AddArc(width - radius, y, radius, radius, , );
gp.AddArc(width - radius, height - radius, radius, radius, , );
gp.AddArc(x, height - radius, radius, radius, , );
gp.CloseAllFigures();
return gp;
} /// <summary>
/// 绘制圆角矩形
/// </summary>
/// <param name="rect">矩形</param>
/// <param name="radius">弯曲程度(0-10),越大越弯曲</param>
/// <returns></returns>
public static GraphicsPath DrawRoundRect(Rectangle rect, int radius)
{
int x = rect.X;
int y = rect.Y;
int width = rect.Width;
int height = rect.Height;
return DrawRoundRect(x, y, width - , height - , radius);
} /// <summary>
/// 得到两种颜色的过渡色(1代表开始色,100表示结束色)
/// </summary>
/// <param name="c">开始色</param>
/// <param name="c2">结束色</param>
/// <param name="value">需要获得的度</param>
/// <returns></returns>
public static Color GetIntermediateColor(Color c, Color c2, int value)
{
float pc = value * 1.0F / ; int ca = c.A, cr = c.R, cg = c.G, cb = c.B;
int c2a = c2.A, c2r = c2.R, c2g = c2.G, c2b = c2.B; int a = (int)Math.Abs(ca + (ca - c2a) * pc);
int r = (int)Math.Abs(cr - ((cr - c2r) * pc));
int g = (int)Math.Abs(cg - ((cg - c2g) * pc));
int b = (int)Math.Abs(cb - ((cb - c2b) * pc)); if (a > ) { a = ; }
if (r > ) { r = ; }
if (g > ) { g = ; }
if (b > ) { b = ; } return (Color.FromArgb(a, r, g, b));
} public static StringFormat StringFormatAlignment(ContentAlignment textalign)
{
StringFormat sf = new StringFormat();
switch (textalign)
{
case ContentAlignment.TopLeft:
case ContentAlignment.TopCenter:
case ContentAlignment.TopRight:
sf.LineAlignment = StringAlignment.Near;
break;
case ContentAlignment.MiddleLeft:
case ContentAlignment.MiddleCenter:
case ContentAlignment.MiddleRight:
sf.LineAlignment = StringAlignment.Center;
break;
case ContentAlignment.BottomLeft:
case ContentAlignment.BottomCenter:
case ContentAlignment.BottomRight:
sf.LineAlignment = StringAlignment.Far;
break;
}
return sf;
} /// <summary>
/// 绘图对像
/// </summary>
/// <param name="g">绘图对像</param>
/// <param name="img">图片</param>
/// <param name="r">绘置的图片大小、坐标</param>
/// <param name="lr">绘置的图片边界</param>
/// <param name="index">当前状态</param>
/// <param name="Totalindex">状态总数</param>
public static void DrawRect(Graphics g, Bitmap img, Rectangle r, Rectangle lr, int index, int Totalindex)
{
if (img == null) return;
Rectangle r1, r2;
int x = (index - ) * img.Width / Totalindex;
int y = ;
int x1 = r.Left;
int y1 = r.Top; if (r.Height > img.Height && r.Width <= img.Width / Totalindex)
{
r1 = new Rectangle(x, y, img.Width / Totalindex, lr.Top);
r2 = new Rectangle(x1, y1, r.Width, lr.Top);
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel); r1 = new Rectangle(x, y + lr.Top, img.Width / Totalindex, img.Height - lr.Top - lr.Bottom);
r2 = new Rectangle(x1, y1 + lr.Top, r.Width, r.Height - lr.Top - lr.Bottom);
if ((lr.Top + lr.Bottom) == ) r1.Height = r1.Height - ;
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel); r1 = new Rectangle(x, y + img.Height - lr.Bottom, img.Width / Totalindex, lr.Bottom);
r2 = new Rectangle(x1, y1 + r.Height - lr.Bottom, r.Width, lr.Bottom);
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
}
else
if (r.Height <= img.Height && r.Width > img.Width / Totalindex)
{
r1 = new Rectangle(x, y, lr.Left, img.Height);
r2 = new Rectangle(x1, y1, lr.Left, r.Height);
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
r1 = new Rectangle(x + lr.Left, y, img.Width / Totalindex - lr.Left - lr.Right, img.Height);
r2 = new Rectangle(x1 + lr.Left, y1, r.Width - lr.Left - lr.Right, r.Height);
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
r1 = new Rectangle(x + img.Width / Totalindex - lr.Right, y, lr.Right, img.Height);
r2 = new Rectangle(x1 + r.Width - lr.Right, y1, lr.Right, r.Height);
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
}
else
if (r.Height <= img.Height && r.Width <= img.Width / Totalindex) { r1 = new Rectangle((index - ) * img.Width / Totalindex, , img.Width / Totalindex, img.Height); g.DrawImage(img, new Rectangle(x1, y1, r.Width, r.Height), r1, GraphicsUnit.Pixel); }
else if (r.Height > img.Height && r.Width > img.Width / Totalindex)
{
//top-left
r1 = new Rectangle(x, y, lr.Left, lr.Top);
r2 = new Rectangle(x1, y1, lr.Left, lr.Top);
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel); //top-bottom
r1 = new Rectangle(x, y + img.Height - lr.Bottom, lr.Left, lr.Bottom);
r2 = new Rectangle(x1, y1 + r.Height - lr.Bottom, lr.Left, lr.Bottom);
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel); //left
r1 = new Rectangle(x, y + lr.Top, lr.Left, img.Height - lr.Top - lr.Bottom);
r2 = new Rectangle(x1, y1 + lr.Top, lr.Left, r.Height - lr.Top - lr.Bottom);
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel); //top
r1 = new Rectangle(x + lr.Left, y,
img.Width / Totalindex - lr.Left - lr.Right, lr.Top);
r2 = new Rectangle(x1 + lr.Left, y1,
r.Width - lr.Left - lr.Right, lr.Top);
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel); //right-top
r1 = new Rectangle(x + img.Width / Totalindex - lr.Right, y, lr.Right, lr.Top);
r2 = new Rectangle(x1 + r.Width - lr.Right, y1, lr.Right, lr.Top);
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel); //Right
r1 = new Rectangle(x + img.Width / Totalindex - lr.Right, y + lr.Top,
lr.Right, img.Height - lr.Top - lr.Bottom);
r2 = new Rectangle(x1 + r.Width - lr.Right, y1 + lr.Top,
lr.Right, r.Height - lr.Top - lr.Bottom);
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel); //right-bottom
r1 = new Rectangle(x + img.Width / Totalindex - lr.Right, y + img.Height - lr.Bottom,
lr.Right, lr.Bottom);
r2 = new Rectangle(x1 + r.Width - lr.Right, y1 + r.Height - lr.Bottom,
lr.Right, lr.Bottom);
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel); //bottom
r1 = new Rectangle(x + lr.Left, y + img.Height - lr.Bottom,
img.Width / Totalindex - lr.Left - lr.Right, lr.Bottom);
r2 = new Rectangle(x1 + lr.Left, y1 + r.Height - lr.Bottom,
r.Width - lr.Left - lr.Right, lr.Bottom);
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel); //Center
r1 = new Rectangle(x + lr.Left, y + lr.Top,
img.Width / Totalindex - lr.Left - lr.Right, img.Height - lr.Top - lr.Bottom);
r2 = new Rectangle(x1 + lr.Left, y1 + lr.Top,
r.Width - lr.Left - lr.Right, r.Height - lr.Top - lr.Bottom);
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
}
} /// <summary>
/// 绘图对像
/// </summary>
/// <param name="g"> 绘图对像</param>
/// <param name="obj">图片对像</param>
/// <param name="r">绘置的图片大小、坐标</param>
/// <param name="index">当前状态</param>
/// <param name="Totalindex">状态总数</param>
public static void DrawRect(Graphics g, Bitmap img, Rectangle r, int index, int Totalindex)
{
if (img == null) return;
int width = img.Width / Totalindex;
int height = img.Height;
Rectangle r1, r2;
int x = (index - ) * width;
int y = ;
r1 = new Rectangle(x, y, width, height);
r2 = new Rectangle(r.Left, r.Top, r.Width, r.Height);
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
} /// <summary>
/// 得到要绘置的图片对像
/// </summary>
/// <param name="str">图像在程序集中的地址</param>
/// <returns></returns>
public static Bitmap GetResBitmap(string str)
{
Stream sm;
sm = FindStream(str);
if (sm == null) return null;
return new Bitmap(sm);
} /// <summary>
/// 得到图程序集中的图片对像
/// </summary>
/// <param name="str">图像在程序集中的地址</param>
/// <returns></returns>
private static Stream FindStream(string str)
{
Assembly assembly = Assembly.GetExecutingAssembly();
string[] resNames = assembly.GetManifestResourceNames();
foreach (string s in resNames)
{
if (s == str)
{
return assembly.GetManifestResourceStream(s);
}
}
return null;
} }
public class Win32
{
#region Window Const public const int WM_KEYDOWN = 0x0100;
public const int WM_KEYUP = 0x0101;
public const int WM_CTLCOLOREDIT = 0x133;
public const int WM_ERASEBKGND = 0x0014;
public const int WM_LBUTTONDOWN = 0x0201;
public const int WM_LBUTTONUP = 0x0202;
public const int WM_LBUTTONDBLCLK = 0x0203;
public const int WM_WINDOWPOSCHANGING = 0x46;
public const int WM_PAINT = 0xF;
public const int WM_CREATE = 0x0001;
public const int WM_ACTIVATE = 0x0006;
public const int WM_NCCREATE = 0x0081;
public const int WM_NCCALCSIZE = 0x0083;
public const int WM_NCPAINT = 0x0085;
public const int WM_NCACTIVATE = 0x0086;
public const int WM_NCLBUTTONDOWN = 0x00A1;
public const int WM_NCLBUTTONUP = 0x00A2;
public const int WM_NCLBUTTONDBLCLK = 0x00A3;
public const int WM_NCMOUSEMOVE = 0x00A0; public const int WM_NCHITTEST = 0x0084; public const int HTLEFT = ;
public const int HTRIGHT = ;
public const int HTTOP = ;
public const int HTTOPLEFT = ;
public const int HTTOPRIGHT = ;
public const int HTBOTTOM = ;
public const int HTBOTTOMLEFT = 0x10;
public const int HTBOTTOMRIGHT = ;
public const int HTCAPTION = ;
public const int HTCLIENT = ; public const int WM_FALSE = ;
public const int WM_TRUE = ; #endregion #region Public extern methods [DllImport("gdi32.dll")]
public static extern int CreateRoundRectRgn(int x1, int y1, int x2, int y2, int x3, int y3); [DllImport("user32.dll")]
public static extern int SetWindowRgn(IntPtr hwnd, int hRgn, Boolean bRedraw); [DllImport("gdi32.dll", EntryPoint = "DeleteObject", CharSet = CharSet.Ansi)]
public static extern int DeleteObject(int hObject); [DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam); [DllImport("user32.dll")]
public static extern bool ReleaseCapture(); #endregion
}
上一篇:C#使用IHttpModule接口修改http输出的方法浅谈


下一篇:Struts2获取演示示例教程