/* 作者:Starts_2000
* 日期:2009-07-30
* 网站:http://www.csharpwin.com CS 程序员之窗。
* 你可以免费使用或修改以下代码,但请保留版权信息。
* 具体请查看 CS程序员之窗开源协议(http://www.csharpwin.com/csol.html)。
*/
[ToolboxBitmap(typeof(CheckBox))]
public class CheckBoxEx : CheckBox
{
private Color _baseColor = Color.FromArgb(, , );
private ControlState _controlState;
private static readonly ContentAlignment RightAlignment =
ContentAlignment.TopRight |
ContentAlignment.BottomRight |
ContentAlignment.MiddleRight;
private static readonly ContentAlignment LeftAligbment =
ContentAlignment.TopLeft |
ContentAlignment.BottomLeft |
ContentAlignment.MiddleLeft;
public CheckBoxEx()
: base()
{
SetStyle(
ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.OptimizedDoubleBuffer |
ControlStyles.ResizeRedraw |
ControlStyles.SupportsTransparentBackColor, true);
}
public Color BaseColor
{
get { return _baseColor; }
set
{
_baseColor = value;
base.Invalidate();
}
}
protected virtual int DefaultCheckButtonWidth
{
get { return ; }
}
internal ControlState ControlState
{
get { return _controlState; }
set
{
if (_controlState != value)
{
_controlState = value;
base.Invalidate();
}
}
}
protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
ControlState = ControlState.Hover;
}
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
ControlState = ControlState.Normal;
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
if (e.Button == MouseButtons.Left && e.Clicks == )
{
ControlState = ControlState.Pressed;
}
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
if (e.Button == MouseButtons.Left && e.Clicks == )
{
if (ClientRectangle.Contains(e.Location))
{
ControlState = ControlState.Hover;
}
else
{
ControlState = ControlState.Normal;
}
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
base.OnPaintBackground(e);
Graphics g = e.Graphics;
Rectangle checkButtonRect;
Rectangle textRect;
CalculateRect(out checkButtonRect, out textRect);
g.SmoothingMode = SmoothingMode.AntiAlias;
Color backColor = ControlPaint.Light(_baseColor);
Color borderColor;
Color innerBorderColor;
Color checkColor;
bool hover = false;
if (Enabled)
{
switch (ControlState)
{
case ControlState.Hover:
borderColor = _baseColor;
innerBorderColor = _baseColor;
checkColor = GetColor(_baseColor, , , , );
hover = true;
break;
case ControlState.Pressed:
borderColor = _baseColor;
innerBorderColor = GetColor(_baseColor, , -, -, -);
checkColor = GetColor(_baseColor, , -, -, -);
hover = true;
break;
default:
borderColor = _baseColor;
innerBorderColor = Color.Empty;
checkColor = _baseColor;
break;
}
}
else
{
borderColor = SystemColors.ControlDark;
innerBorderColor = SystemColors.ControlDark;
checkColor = SystemColors.ControlDark;
}
using (SolidBrush brush = new SolidBrush(Color.White))
{
g.FillRectangle(brush, checkButtonRect);
}
if (hover)
{
using (Pen pen = new Pen(innerBorderColor, 2F))
{
g.DrawRectangle(pen, checkButtonRect);
}
}
switch (CheckState)
{
case CheckState.Checked:
DrawCheckedFlag(
g,
checkButtonRect,
checkColor);
break;
case CheckState.Indeterminate:
checkButtonRect.Inflate(-, -);
using (GraphicsPath path = new GraphicsPath())
{
path.AddEllipse(checkButtonRect);
using (PathGradientBrush brush = new PathGradientBrush(path))
{
brush.CenterColor = checkColor;
brush.SurroundColors = new Color[] { Color.White };
Blend blend = new Blend();
blend.Positions = new float[] { 0f, 0.4f, 1f };
blend.Factors = new float[] { 0f, 0.3f, 1f };
brush.Blend = blend;
g.FillEllipse(brush, checkButtonRect);
}
}
checkButtonRect.Inflate(, );
break;
}
using (Pen pen = new Pen(borderColor))
{
g.DrawRectangle(pen, checkButtonRect);
}
Color textColor = Enabled ? ForeColor : SystemColors.GrayText;
TextRenderer.DrawText(
g,
Text,
Font,
textRect,
textColor,
GetTextFormatFlags(TextAlign, RightToLeft == RightToLeft.Yes));
}
private void CalculateRect(
out Rectangle checkButtonRect, out Rectangle textRect)
{
checkButtonRect = new Rectangle(
, , DefaultCheckButtonWidth, DefaultCheckButtonWidth);
textRect = Rectangle.Empty;
bool bCheckAlignLeft = (int)(LeftAligbment & CheckAlign) != ;
bool bCheckAlignRight = (int)(RightAlignment & CheckAlign) != ;
bool bRightToLeft = RightToLeft == RightToLeft.Yes;
if ((bCheckAlignLeft && !bRightToLeft) ||
(bCheckAlignRight && bRightToLeft))
{
switch (CheckAlign)
{
case ContentAlignment.TopRight:
case ContentAlignment.TopLeft:
checkButtonRect.Y = ;
break;
case ContentAlignment.MiddleRight:
case ContentAlignment.MiddleLeft:
checkButtonRect.Y = (Height - DefaultCheckButtonWidth) / ;
break;
case ContentAlignment.BottomRight:
case ContentAlignment.BottomLeft:
checkButtonRect.Y = Height - DefaultCheckButtonWidth - ;
break;
}
checkButtonRect.X = ;
textRect = new Rectangle(
checkButtonRect.Right + ,
,
Width - checkButtonRect.Right - ,
Height);
}
else if ((bCheckAlignRight && !bRightToLeft)
|| (bCheckAlignLeft && bRightToLeft))
{
switch (CheckAlign)
{
case ContentAlignment.TopLeft:
case ContentAlignment.TopRight:
checkButtonRect.Y = ;
break;
case ContentAlignment.MiddleLeft:
case ContentAlignment.MiddleRight:
checkButtonRect.Y = (Height - DefaultCheckButtonWidth) / ;
break;
case ContentAlignment.BottomLeft:
case ContentAlignment.BottomRight:
checkButtonRect.Y = Height - DefaultCheckButtonWidth - ;
break;
}
checkButtonRect.X = Width - DefaultCheckButtonWidth - ;
textRect = new Rectangle(
, , Width - DefaultCheckButtonWidth - , Height);
}
else
{
switch (CheckAlign)
{
case ContentAlignment.TopCenter:
checkButtonRect.Y = ;
textRect.Y = checkButtonRect.Bottom + ;
textRect.Height = Height - DefaultCheckButtonWidth - ;
break;
case ContentAlignment.MiddleCenter:
checkButtonRect.Y = (Height - DefaultCheckButtonWidth) / ;
textRect.Y = ;
textRect.Height = Height;
break;
case ContentAlignment.BottomCenter:
checkButtonRect.Y = Height - DefaultCheckButtonWidth - ;
textRect.Y = ;
textRect.Height = Height - DefaultCheckButtonWidth - ;
break;
}
checkButtonRect.X = (Width - DefaultCheckButtonWidth) / ;
textRect.X = ;
textRect.Width = Width - ;
}
}
private void DrawCheckedFlag(Graphics graphics, Rectangle rect, Color color)
{
PointF[] points = new PointF[];
points[] = new PointF(
rect.X + rect.Width / 4.5f,
rect.Y + rect.Height / 2.5f);
points[] = new PointF(
rect.X + rect.Width / 2.5f,
rect.Bottom - rect.Height / 3f);
points[] = new PointF(
rect.Right - rect.Width / 4.0f,
rect.Y + rect.Height / 4.5f);
using (Pen pen = new Pen(color, 2F))
{
graphics.DrawLines(pen, points);
}
}
private Color GetColor(Color colorBase, int a, int r, int g, int b)
{
int a0 = colorBase.A;
int r0 = colorBase.R;
int g0 = colorBase.G;
int b0 = colorBase.B;
if (a + a0 > ) { a = ; } else { a = Math.Max(a + a0, ); }
if (r + r0 > ) { r = ; } else { r = Math.Max(r + r0, ); }
if (g + g0 > ) { g = ; } else { g = Math.Max(g + g0, ); }
if (b + b0 > ) { b = ; } else { b = Math.Max(b + b0, ); }
return Color.FromArgb(a, r, g, b);
}
internal static TextFormatFlags GetTextFormatFlags(
ContentAlignment alignment,
bool rightToleft)
{
TextFormatFlags flags = TextFormatFlags.WordBreak |
TextFormatFlags.SingleLine;
if (rightToleft)
{
flags |= TextFormatFlags.RightToLeft | TextFormatFlags.Right;
}
switch (alignment)
{
case ContentAlignment.BottomCenter:
flags |= TextFormatFlags.Bottom | TextFormatFlags.HorizontalCenter;
break;
case ContentAlignment.BottomLeft:
flags |= TextFormatFlags.Bottom | TextFormatFlags.Left;
break;
case ContentAlignment.BottomRight:
flags |= TextFormatFlags.Bottom | TextFormatFlags.Right;
break;
case ContentAlignment.MiddleCenter:
flags |= TextFormatFlags.HorizontalCenter |
TextFormatFlags.VerticalCenter;
break;
case ContentAlignment.MiddleLeft:
flags |= TextFormatFlags.VerticalCenter | TextFormatFlags.Left;
break;
case ContentAlignment.MiddleRight:
flags |= TextFormatFlags.VerticalCenter | TextFormatFlags.Right;
break;
case ContentAlignment.TopCenter:
flags |= TextFormatFlags.Top | TextFormatFlags.HorizontalCenter;
break;
case ContentAlignment.TopLeft:
flags |= TextFormatFlags.Top | TextFormatFlags.Left;
break;
case ContentAlignment.TopRight:
flags |= TextFormatFlags.Top | TextFormatFlags.Right;
break;
}
return flags;
}
}
/// <summary>
/// 控件的状态。
/// </summary>
internal enum ControlState
{
/// <summary>
/// 正常。
/// </summary>
Normal,
/// <summary>
/// 鼠标进入。
/// </summary>
Hover,
/// <summary>
/// 鼠标按下。
/// </summary>
Pressed,
/// <summary>
/// 获得焦点。
/// </summary>
Focused,
}