using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel;
namespace LYFZ.ComponentLibrary
{
public class RadioButtonEx:System.Windows.Forms.RadioButton
{
public enum QQControlState
{
///
/// 正常状态
///
Normal = 0,
///
/// /鼠标进入
///
Highlight = 1,
///
/// 鼠标按下
///
Down = 2,
///
/// 获得焦点
///
Focus = 3,
///
/// 控件禁止
///
Disabled = 4
}
///
/// 返回给定的颜色的ARGB的分量差值的颜色
///
///
/// A
/// R
/// G
/// B
///
public static 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 > 255) { a = 255; } else { a = Math.Max(a + a0, 0); }
if (r + r0 > 255) { r = 255; } else { r = Math.Max(r + r0, 0); }
if (g + g0 > 255) { g = 255; } else { g = Math.Max(g + g0, 0); }
if (b + b0 > 255) { b = 255; } else { b = Math.Max(b + b0, 0); }
return Color.FromArgb(a, r, g, b);
}
internal class ColorTable
{
public static Color QQBorderColor = Color.LightBlue; //LightBlue = Color.FromArgb(173, 216, 230)
public static Color QQHighLightColor = GetColor(QQBorderColor, 255, -63, -11, 23); //Color.FromArgb(110, 205, 253)
public static Color QQHighLightInnerColor = GetColor(QQBorderColor, 255, -100, -44, 1); //Color.FromArgb(73, 172, 231);
}
#region Field
private QQControlState _state = QQControlState.Normal;
private Image _dotImg = new Bitmap(LYFZ.ComponentLibrary.Properties.Resources.dot);
private Font _defaultFont = new Font("微软雅黑", 9);
private static readonly ContentAlignment RightAlignment = ContentAlignment.TopRight | ContentAlignment.BottomRight | ContentAlignment.MiddleRight;
private static readonly ContentAlignment LeftAlignment = ContentAlignment.TopLeft | ContentAlignment.BottomLeft | ContentAlignment.MiddleLeft;
#endregion
#region Constructor
public RadioButtonEx()
{
SetStyles();
this.BackColor = Color.Transparent;
this.Font = _defaultFont;
}
#endregion
#region Properites
[Description("获取RadioButton左边正方形的宽度")]
protected virtual int CheckRectWidth
{
get { return 12; }
}
#endregion
#region Override
protected override void OnMouseEnter(EventArgs e)
{
_state = QQControlState.Highlight;
base.OnMouseEnter(e);
}
protected override void OnMouseLeave(EventArgs e)
{
_state = QQControlState.Normal;
base.OnMouseLeave(e);
}
protected override void OnMouseDown(MouseEventArgs mevent)
{
if (mevent.Button == MouseButtons.Left)
{
_state = QQControlState.Down;
}
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.Normal;
}
}
base.OnMouseUp(mevent);
}
protected override void OnEnabledChanged(EventArgs e)
{
if (Enabled)
{
_state = QQControlState.Normal;
}
else
{
_state = QQControlState.Disabled;
}
base.OnEnabledChanged(e);
}
protected override void OnPaint(PaintEventArgs pevent)
{
base.OnPaint(pevent);
base.OnPaintBackground(pevent);
Graphics g = pevent.Graphics;
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
Rectangle circleRect, textRect;
CalculateRect(out circleRect, out textRect);
if (Enabled == false)
{
_state = QQControlState.Disabled;
}
switch (_state)
{
case QQControlState.Highlight:
case QQControlState.Down:
DrawHighLightCircle(g, circleRect);
break;
case QQControlState.Disabled:
DrawDisabledCircle(g, circleRect);
break;
default:
DrawNormalCircle(g, circleRect);
break;
}
Color textColor = (Enabled == true) ? ForeColor : SystemColors.GrayText;
TextRenderer.DrawText(
g,
Text,
Font,
textRect,
textColor,
GetTextFormatFlags(TextAlign, RightToLeft == RightToLeft.Yes));
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (_dotImg != null)
{
_dotImg.Dispose();
}
if (_defaultFont != null)
{
_defaultFont.Dispose();
}
}
_dotImg = null;
_defaultFont = null;
base.Dispose(disposing);
}
#endregion
#region Private
private void DrawNormalCircle(Graphics g, Rectangle circleRect)
{
g.FillEllipse(Brushes.White, circleRect);
using (Pen borderPen = new Pen(ColorTable.QQBorderColor))
{
g.DrawEllipse(borderPen, circleRect);
}
if (Checked)
{
circleRect.Inflate(-2, -2);
g.DrawImage(
_dotImg,
new Rectangle(circleRect.X + 1, circleRect.Y + 1, circleRect.Width - 1, circleRect.Height - 1),
0,
0,
_dotImg.Width,
_dotImg.Height,
GraphicsUnit.Pixel);
}
}
private void DrawHighLightCircle(Graphics g, Rectangle circleRect)
{
DrawNormalCircle(g, circleRect);
using (Pen p = new Pen(ColorTable.QQHighLightInnerColor))
{
g.DrawEllipse(p, circleRect);
circleRect.Inflate(1, 1);
p.Color = ColorTable.QQHighLightColor;
g.DrawEllipse(p, circleRect);
}
}
private void DrawDisabledCircle(Graphics g, Rectangle circleRect)
{
g.DrawEllipse(SystemPens.ControlDark, circleRect);
if (Checked)
{
circleRect.Inflate(-2, -2);
g.DrawImage(
_dotImg,
new Rectangle(circleRect.X + 1, circleRect.Y + 1, circleRect.Width - 1, circleRect.Height - 1),
0,
0,
_dotImg.Width,
_dotImg.Height,
GraphicsUnit.Pixel);
}
}
private void SetStyles()
{
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
UpdateStyles();
}
private void CalculateRect(out Rectangle circleRect, out Rectangle textRect)
{
circleRect = new Rectangle(
0, 0, CheckRectWidth, CheckRectWidth);
textRect = Rectangle.Empty;
bool bCheckAlignLeft = (int)(LeftAlignment & CheckAlign) != 0;
bool bCheckAlignRight = (int)(RightAlignment & CheckAlign) != 0;
bool bRightToLeft = (RightToLeft == RightToLeft.Yes);
if ((bCheckAlignLeft && !bRightToLeft) ||
(bCheckAlignRight && bRightToLeft))
{
switch (CheckAlign)
{
case ContentAlignment.TopRight:
case ContentAlignment.TopLeft:
circleRect.Y = 2;
break;
case ContentAlignment.MiddleRight:
case ContentAlignment.MiddleLeft:
circleRect.Y = (Height - CheckRectWidth) / 2;
break;
case ContentAlignment.BottomRight:
case ContentAlignment.BottomLeft:
circleRect.Y = Height - CheckRectWidth - 2;
break;
}
circleRect.X = 1;
textRect = new Rectangle(
circleRect.Right + 2,
0,
Width - circleRect.Right - 4,
Height);
}
else if ((bCheckAlignRight && !bRightToLeft)
|| (bCheckAlignLeft && bRightToLeft))
{
switch (CheckAlign)
{
case ContentAlignment.TopLeft:
case ContentAlignment.TopRight:
circleRect.Y = 2;
break;
case ContentAlignment.MiddleLeft:
case ContentAlignment.MiddleRight:
circleRect.Y = (Height - CheckRectWidth) / 2;
break;
case ContentAlignment.BottomLeft:
case ContentAlignment.BottomRight:
circleRect.Y = Height - CheckRectWidth - 2;
break;
}
circleRect.X = Width - CheckRectWidth - 1;
textRect = new Rectangle(
2, 0, Width - CheckRectWidth - 6, Height);
}
else
{
switch (CheckAlign)
{
case ContentAlignment.TopCenter:
circleRect.Y = 2;
textRect.Y = circleRect.Bottom + 2;
textRect.Height = Height - CheckRectWidth - 6;
break;
case ContentAlignment.MiddleCenter:
circleRect.Y = (Height - CheckRectWidth) / 2;
textRect.Y = 0;
textRect.Height = Height;
break;
case ContentAlignment.BottomCenter:
circleRect.Y = Height - CheckRectWidth - 2;
textRect.Y = 0;
textRect.Height = Height - CheckRectWidth - 6;
break;
}
circleRect.X = (Width - CheckRectWidth) / 2;
textRect.X = 2;
textRect.Width = Width - 4;
}
}
private 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;
}
#endregion
}
}