RadioButtonEx.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Windows.Forms;
  5. using System.IO;
  6. using System.Drawing;
  7. using System.Drawing.Drawing2D;
  8. using System.ComponentModel;
  9. namespace LYFZ.ComponentLibrary
  10. {
  11. public class RadioButtonEx:System.Windows.Forms.RadioButton
  12. {
  13. public enum QQControlState
  14. {
  15. /// <summary>
  16. /// 正常状态
  17. /// </summary>
  18. Normal = 0,
  19. /// <summary>
  20. /// /鼠标进入
  21. /// </summary>
  22. Highlight = 1,
  23. /// <summary>
  24. /// 鼠标按下
  25. /// </summary>
  26. Down = 2,
  27. /// <summary>
  28. /// 获得焦点
  29. /// </summary>
  30. Focus = 3,
  31. /// <summary>
  32. /// 控件禁止
  33. /// </summary>
  34. Disabled = 4
  35. }
  36. /// <summary>
  37. /// 返回给定的颜色的ARGB的分量差值的颜色
  38. /// </summary>
  39. /// <param name="colorBase"></param>
  40. /// <param name="a">A</param>
  41. /// <param name="r">R</param>
  42. /// <param name="g">G</param>
  43. /// <param name="b">B</param>
  44. /// <returns></returns>
  45. public static Color GetColor(Color colorBase, int a, int r, int g, int b)
  46. {
  47. int a0 = colorBase.A;
  48. int r0 = colorBase.R;
  49. int g0 = colorBase.G;
  50. int b0 = colorBase.B;
  51. if (a + a0 > 255) { a = 255; } else { a = Math.Max(a + a0, 0); }
  52. if (r + r0 > 255) { r = 255; } else { r = Math.Max(r + r0, 0); }
  53. if (g + g0 > 255) { g = 255; } else { g = Math.Max(g + g0, 0); }
  54. if (b + b0 > 255) { b = 255; } else { b = Math.Max(b + b0, 0); }
  55. return Color.FromArgb(a, r, g, b);
  56. }
  57. internal class ColorTable
  58. {
  59. public static Color QQBorderColor = LYFZ.ComponentLibrary.GetUIResources.CheckBoxExBorderColor;//Color.LightBlue; //LightBlue = Color.FromArgb(173, 216, 230)
  60. public static Color QQHighLightColor = GetColor(QQBorderColor, 255, -63, -11, 23); //Color.FromArgb(110, 205, 253)
  61. public static Color QQHighLightInnerColor = GetColor(QQBorderColor, 255, -100, -44, 1); //Color.FromArgb(73, 172, 231);
  62. }
  63. #region Field
  64. private QQControlState _state = QQControlState.Normal;
  65. private Image _dotImg = new Bitmap(LYFZ.ComponentLibrary.GetUIResources.dot);
  66. private Font _defaultFont = new Font("微软雅黑", 9);
  67. private static readonly ContentAlignment RightAlignment = ContentAlignment.TopRight | ContentAlignment.BottomRight | ContentAlignment.MiddleRight;
  68. private static readonly ContentAlignment LeftAlignment = ContentAlignment.TopLeft | ContentAlignment.BottomLeft | ContentAlignment.MiddleLeft;
  69. #endregion
  70. #region Constructor
  71. public RadioButtonEx()
  72. {
  73. SetStyles();
  74. this.BackColor = Color.Transparent;
  75. this.ForeColor = LYFZ.ComponentLibrary.GetUIResources.DefaultTextColor;
  76. _defaultFont = new System.Drawing.Font("微软雅黑", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel, ((byte)(134)));
  77. this.Font = _defaultFont;
  78. // this.Paint += RadioButtonEx_Paint;
  79. }
  80. void RadioButtonEx_Paint(object sender, PaintEventArgs e)
  81. {
  82. this.ForeColor = LYFZ.ComponentLibrary.GetUIResources.DefaultTextColor;
  83. }
  84. #endregion
  85. #region Properites
  86. [Description("获取RadioButton左边正方形的宽度")]
  87. protected virtual int CheckRectWidth
  88. {
  89. get { return 12; }
  90. }
  91. #endregion
  92. #region Override
  93. protected override void OnMouseEnter(EventArgs e)
  94. {
  95. _state = QQControlState.Highlight;
  96. base.OnMouseEnter(e);
  97. }
  98. protected override void OnMouseLeave(EventArgs e)
  99. {
  100. _state = QQControlState.Normal;
  101. base.OnMouseLeave(e);
  102. }
  103. protected override void OnMouseDown(MouseEventArgs mevent)
  104. {
  105. if (mevent.Button == MouseButtons.Left)
  106. {
  107. _state = QQControlState.Down;
  108. }
  109. base.OnMouseDown(mevent);
  110. }
  111. protected override void OnMouseUp(MouseEventArgs mevent)
  112. {
  113. if (mevent.Button == MouseButtons.Left)
  114. {
  115. if (ClientRectangle.Contains(mevent.Location))
  116. {
  117. _state = QQControlState.Highlight;
  118. }
  119. else
  120. {
  121. _state = QQControlState.Normal;
  122. }
  123. }
  124. base.OnMouseUp(mevent);
  125. }
  126. protected override void OnEnabledChanged(EventArgs e)
  127. {
  128. if (Enabled)
  129. {
  130. _state = QQControlState.Normal;
  131. }
  132. else
  133. {
  134. _state = QQControlState.Disabled;
  135. }
  136. base.OnEnabledChanged(e);
  137. }
  138. protected override void OnPaint(PaintEventArgs pevent)
  139. {
  140. base.OnPaint(pevent);
  141. base.OnPaintBackground(pevent);
  142. Graphics g = pevent.Graphics;
  143. g.SmoothingMode = SmoothingMode.AntiAlias;
  144. g.InterpolationMode = InterpolationMode.HighQualityBicubic;
  145. Rectangle circleRect, textRect;
  146. CalculateRect(out circleRect, out textRect);
  147. if (Enabled == false)
  148. {
  149. _state = QQControlState.Disabled;
  150. }
  151. switch (_state)
  152. {
  153. case QQControlState.Highlight:
  154. case QQControlState.Down:
  155. DrawHighLightCircle(g, circleRect);
  156. break;
  157. case QQControlState.Disabled:
  158. DrawDisabledCircle(g, circleRect);
  159. break;
  160. default:
  161. DrawNormalCircle(g, circleRect);
  162. break;
  163. }
  164. Color textColor = (Enabled == true) ? ForeColor : SystemColors.GrayText;
  165. TextRenderer.DrawText(
  166. g,
  167. Text,
  168. Font,
  169. textRect,
  170. textColor,
  171. GetTextFormatFlags(TextAlign, RightToLeft == RightToLeft.Yes));
  172. }
  173. protected override void Dispose(bool disposing)
  174. {
  175. if (disposing)
  176. {
  177. if (_dotImg != null)
  178. {
  179. _dotImg.Dispose();
  180. }
  181. if (_defaultFont != null)
  182. {
  183. _defaultFont.Dispose();
  184. }
  185. }
  186. _dotImg = null;
  187. _defaultFont = null;
  188. base.Dispose(disposing);
  189. }
  190. #endregion
  191. #region Private
  192. private void DrawNormalCircle(Graphics g, Rectangle circleRect)
  193. {
  194. g.FillEllipse(Brushes.White, circleRect);
  195. using (Pen borderPen = new Pen(ColorTable.QQBorderColor))
  196. {
  197. g.DrawEllipse(borderPen, circleRect);
  198. }
  199. if (Checked)
  200. {
  201. circleRect.Inflate(-2, -2);
  202. g.DrawImage(
  203. _dotImg,
  204. new Rectangle(circleRect.X + 1, circleRect.Y + 1, circleRect.Width - 1, circleRect.Height - 1),
  205. 0,
  206. 0,
  207. _dotImg.Width,
  208. _dotImg.Height,
  209. GraphicsUnit.Pixel);
  210. }
  211. }
  212. private void DrawHighLightCircle(Graphics g, Rectangle circleRect)
  213. {
  214. DrawNormalCircle(g, circleRect);
  215. using (Pen p = new Pen(ColorTable.QQHighLightInnerColor))
  216. {
  217. g.DrawEllipse(p, circleRect);
  218. circleRect.Inflate(1, 1);
  219. p.Color = ColorTable.QQHighLightColor;
  220. g.DrawEllipse(p, circleRect);
  221. }
  222. }
  223. private void DrawDisabledCircle(Graphics g, Rectangle circleRect)
  224. {
  225. g.DrawEllipse(SystemPens.ControlDark, circleRect);
  226. if (Checked)
  227. {
  228. circleRect.Inflate(-2, -2);
  229. g.DrawImage(
  230. _dotImg,
  231. new Rectangle(circleRect.X + 1, circleRect.Y + 1, circleRect.Width - 1, circleRect.Height - 1),
  232. 0,
  233. 0,
  234. _dotImg.Width,
  235. _dotImg.Height,
  236. GraphicsUnit.Pixel);
  237. }
  238. }
  239. private void SetStyles()
  240. {
  241. SetStyle(ControlStyles.UserPaint, true);
  242. SetStyle(ControlStyles.AllPaintingInWmPaint, true);
  243. SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
  244. SetStyle(ControlStyles.ResizeRedraw, true);
  245. SetStyle(ControlStyles.SupportsTransparentBackColor, true);
  246. UpdateStyles();
  247. }
  248. private void CalculateRect(out Rectangle circleRect, out Rectangle textRect)
  249. {
  250. circleRect = new Rectangle(
  251. 0, 0, CheckRectWidth, CheckRectWidth);
  252. textRect = Rectangle.Empty;
  253. bool bCheckAlignLeft = (int)(LeftAlignment & CheckAlign) != 0;
  254. bool bCheckAlignRight = (int)(RightAlignment & CheckAlign) != 0;
  255. bool bRightToLeft = (RightToLeft == RightToLeft.Yes);
  256. if ((bCheckAlignLeft && !bRightToLeft) ||
  257. (bCheckAlignRight && bRightToLeft))
  258. {
  259. switch (CheckAlign)
  260. {
  261. case ContentAlignment.TopRight:
  262. case ContentAlignment.TopLeft:
  263. circleRect.Y = 2;
  264. break;
  265. case ContentAlignment.MiddleRight:
  266. case ContentAlignment.MiddleLeft:
  267. circleRect.Y = (Height - CheckRectWidth) / 2;
  268. break;
  269. case ContentAlignment.BottomRight:
  270. case ContentAlignment.BottomLeft:
  271. circleRect.Y = Height - CheckRectWidth - 2;
  272. break;
  273. }
  274. circleRect.X = 1;
  275. textRect = new Rectangle(
  276. circleRect.Right + 2,
  277. 0,
  278. Width - circleRect.Right - 4,
  279. Height);
  280. }
  281. else if ((bCheckAlignRight && !bRightToLeft)
  282. || (bCheckAlignLeft && bRightToLeft))
  283. {
  284. switch (CheckAlign)
  285. {
  286. case ContentAlignment.TopLeft:
  287. case ContentAlignment.TopRight:
  288. circleRect.Y = 2;
  289. break;
  290. case ContentAlignment.MiddleLeft:
  291. case ContentAlignment.MiddleRight:
  292. circleRect.Y = (Height - CheckRectWidth) / 2;
  293. break;
  294. case ContentAlignment.BottomLeft:
  295. case ContentAlignment.BottomRight:
  296. circleRect.Y = Height - CheckRectWidth - 2;
  297. break;
  298. }
  299. circleRect.X = Width - CheckRectWidth - 1;
  300. textRect = new Rectangle(
  301. 2, 0, Width - CheckRectWidth - 6, Height);
  302. }
  303. else
  304. {
  305. switch (CheckAlign)
  306. {
  307. case ContentAlignment.TopCenter:
  308. circleRect.Y = 2;
  309. textRect.Y = circleRect.Bottom + 2;
  310. textRect.Height = Height - CheckRectWidth - 6;
  311. break;
  312. case ContentAlignment.MiddleCenter:
  313. circleRect.Y = (Height - CheckRectWidth) / 2;
  314. textRect.Y = 0;
  315. textRect.Height = Height;
  316. break;
  317. case ContentAlignment.BottomCenter:
  318. circleRect.Y = Height - CheckRectWidth - 2;
  319. textRect.Y = 0;
  320. textRect.Height = Height - CheckRectWidth - 6;
  321. break;
  322. }
  323. circleRect.X = (Width - CheckRectWidth) / 2;
  324. textRect.X = 2;
  325. textRect.Width = Width - 4;
  326. }
  327. }
  328. private static TextFormatFlags GetTextFormatFlags(ContentAlignment alignment, bool rightToleft)
  329. {
  330. TextFormatFlags flags = TextFormatFlags.WordBreak |
  331. TextFormatFlags.SingleLine;
  332. if (rightToleft)
  333. {
  334. flags |= TextFormatFlags.RightToLeft | TextFormatFlags.Right;
  335. }
  336. switch (alignment)
  337. {
  338. case ContentAlignment.BottomCenter:
  339. flags |= TextFormatFlags.Bottom | TextFormatFlags.HorizontalCenter;
  340. break;
  341. case ContentAlignment.BottomLeft:
  342. flags |= TextFormatFlags.Bottom | TextFormatFlags.Left;
  343. break;
  344. case ContentAlignment.BottomRight:
  345. flags |= TextFormatFlags.Bottom | TextFormatFlags.Right;
  346. break;
  347. case ContentAlignment.MiddleCenter:
  348. flags |= TextFormatFlags.HorizontalCenter |
  349. TextFormatFlags.VerticalCenter;
  350. break;
  351. case ContentAlignment.MiddleLeft:
  352. flags |= TextFormatFlags.VerticalCenter | TextFormatFlags.Left;
  353. break;
  354. case ContentAlignment.MiddleRight:
  355. flags |= TextFormatFlags.VerticalCenter | TextFormatFlags.Right;
  356. break;
  357. case ContentAlignment.TopCenter:
  358. flags |= TextFormatFlags.Top | TextFormatFlags.HorizontalCenter;
  359. break;
  360. case ContentAlignment.TopLeft:
  361. flags |= TextFormatFlags.Top | TextFormatFlags.Left;
  362. break;
  363. case ContentAlignment.TopRight:
  364. flags |= TextFormatFlags.Top | TextFormatFlags.Right;
  365. break;
  366. }
  367. return flags;
  368. }
  369. #endregion
  370. }
  371. }