CheckBoxEx.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589
  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 CheckBoxEx:System.Windows.Forms.CheckBox
  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. internal class ColorTable
  37. {
  38. public static Color QQBorderColor = LYFZ.ComponentLibrary.GetUIResources.CheckBoxExBorderColor;// Color.LightBlue; //LightBlue = Color.FromArgb(173, 216, 230)
  39. public static Color QQHighLightColor = GetColor(QQBorderColor, 255, -63, -11, 23); //Color.FromArgb(110, 205, 253)
  40. public static Color QQHighLightInnerColor = GetColor(QQBorderColor, 255, -100, -44, 1); //Color.FromArgb(73, 172, 231);
  41. }
  42. /// <summary>
  43. /// 返回给定的颜色的ARGB的分量差值的颜色
  44. /// </summary>
  45. /// <param name="colorBase"></param>
  46. /// <param name="a">A</param>
  47. /// <param name="r">R</param>
  48. /// <param name="g">G</param>
  49. /// <param name="b">B</param>
  50. /// <returns></returns>
  51. public static Color GetColor(Color colorBase, int a, int r, int g, int b)
  52. {
  53. int a0 = colorBase.A;
  54. int r0 = colorBase.R;
  55. int g0 = colorBase.G;
  56. int b0 = colorBase.B;
  57. if (a + a0 > 255) { a = 255; } else { a = Math.Max(a + a0, 0); }
  58. if (r + r0 > 255) { r = 255; } else { r = Math.Max(r + r0, 0); }
  59. if (g + g0 > 255) { g = 255; } else { g = Math.Max(g + g0, 0); }
  60. if (b + b0 > 255) { b = 255; } else { b = Math.Max(b + b0, 0); }
  61. return Color.FromArgb(a, r, g, b);
  62. }
  63. #region Field
  64. private QQControlState _state = QQControlState.Normal;
  65. private Image _checkImg = new Bitmap(LYFZ.ComponentLibrary.GetUIResources.check);
  66. private Image _checkImgDel = new Bitmap(LYFZ.ComponentLibrary.GetUIResources.checkDel);
  67. /// <summary>
  68. /// 特别状态时的图片
  69. /// </summary>
  70. private Image _checkImgSpecially = new Bitmap(LYFZ.ComponentLibrary.GetUIResources.check_Gr);
  71. private Font _defaultFont = new Font("微软雅黑", 9);
  72. private static readonly ContentAlignment RightAlignment = ContentAlignment.TopRight | ContentAlignment.BottomRight | ContentAlignment.MiddleRight;
  73. private static readonly ContentAlignment LeftAlignment = ContentAlignment.TopLeft | ContentAlignment.BottomLeft | ContentAlignment.MiddleLeft;
  74. /// <summary>
  75. /// 当前状态图片
  76. /// </summary>
  77. private Image currentStateImage = new Bitmap(LYFZ.ComponentLibrary.GetUIResources.check_Gr);
  78. #endregion
  79. #region Constructor
  80. public CheckBoxEx()
  81. {
  82. SetStyles();
  83. this.BackColor = Color.Transparent;
  84. this.ForeColor = LYFZ.ComponentLibrary.GetUIResources.DefaultTextColor;
  85. _defaultFont = new System.Drawing.Font("微软雅黑", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel, ((byte)(134)));
  86. this.Font = _defaultFont;
  87. this.CheckStateChanged += CheckBoxEx_CheckStateChanged;
  88. this.CheckedChanged += CheckBoxEx_CheckedChanged;
  89. // this.Paint += CheckBoxEx_Paint;
  90. }
  91. void CheckBoxEx_Paint(object sender, PaintEventArgs e)
  92. {
  93. this.ForeColor = LYFZ.ComponentLibrary.GetUIResources.DefaultTextColor;
  94. }
  95. bool isGreenTick = false;
  96. /// <summary>
  97. /// 在开启四种状态下 但又关闭ThreeState功能时 设为true时 显示绿是勾选
  98. /// </summary>
  99. public bool IsGreenTick
  100. {
  101. get { return isGreenTick; }
  102. set { isGreenTick = value; }
  103. }
  104. void CheckBoxEx_CheckedChanged(object sender, EventArgs e)
  105. {
  106. if (this.Fourstates)
  107. {
  108. if (this.ThreeState)
  109. {
  110. if (this.Checked)
  111. {
  112. this.CurrentCheckState = CheckStateEx.Checked;
  113. }
  114. }
  115. else {
  116. if (this.Checked || IsGreenTick)
  117. {
  118. this.CurrentCheckState = CheckStateEx.Checked;
  119. }
  120. else {
  121. this.CurrentCheckState = CheckStateEx.Indeterminate;
  122. }
  123. }
  124. }
  125. }
  126. void CheckBoxEx_CheckStateChanged(object sender, EventArgs e)
  127. {
  128. if (this.Fourstates)
  129. {
  130. switch (this.CheckState)
  131. {
  132. case System.Windows.Forms.CheckState.Checked:
  133. this.CurrentCheckState = CheckStateEx.Checked;
  134. break;
  135. case System.Windows.Forms.CheckState.Indeterminate:
  136. this.CurrentCheckState = CheckStateEx.Indeterminate;
  137. break;
  138. case System.Windows.Forms.CheckState.Unchecked:
  139. if (this.ThreeState || IsGreenTick)
  140. {
  141. this.CurrentCheckState = CheckStateEx.Unchecked;
  142. }
  143. else {
  144. this.CurrentCheckState = CheckStateEx.Indeterminate;
  145. }
  146. break;
  147. }
  148. }
  149. }
  150. #endregion
  151. #region Properites
  152. [Description("获取CheckBox左边正方形的宽度")]
  153. protected virtual int CheckRectWidth
  154. {
  155. get { return 13; }
  156. }
  157. #endregion
  158. CheckStateEx currentCheckState = CheckStateEx.Unchecked;
  159. /// <summary>
  160. /// 扩展当前状态
  161. /// </summary>
  162. public CheckStateEx CurrentCheckState
  163. {
  164. get { return currentCheckState; }
  165. set { currentCheckState = value;
  166. this.Invalidate();
  167. }
  168. }
  169. bool fourstates = false;
  170. /// <summary>
  171. /// 是否开启四种状态显示
  172. /// </summary>
  173. public bool Fourstates
  174. {
  175. get { return fourstates; }
  176. set {
  177. this.ThreeState = value;
  178. fourstates = value; }
  179. }
  180. #region Override
  181. protected override void OnMouseEnter(EventArgs e)
  182. {
  183. _state = QQControlState.Highlight;
  184. base.OnMouseEnter(e);
  185. }
  186. protected override void OnMouseLeave(EventArgs e)
  187. {
  188. _state = QQControlState.Normal;
  189. base.OnMouseLeave(e);
  190. }
  191. protected override void OnMouseDown(MouseEventArgs mevent)
  192. {
  193. if (mevent.Button == MouseButtons.Left)
  194. {
  195. _state = QQControlState.Down;
  196. }
  197. base.OnMouseDown(mevent);
  198. }
  199. protected override void OnMouseUp(MouseEventArgs mevent)
  200. {
  201. if (mevent.Button == MouseButtons.Left)
  202. {
  203. if (ClientRectangle.Contains(mevent.Location))
  204. {
  205. _state = QQControlState.Highlight;
  206. }
  207. else
  208. {
  209. _state = QQControlState.Normal;
  210. }
  211. }
  212. base.OnMouseUp(mevent);
  213. }
  214. protected override void OnEnabledChanged(EventArgs e)
  215. {
  216. if (Enabled)
  217. {
  218. _state = QQControlState.Normal;
  219. }
  220. else
  221. {
  222. _state = QQControlState.Disabled;
  223. }
  224. base.OnEnabledChanged(e);
  225. }
  226. protected override void OnPaint(PaintEventArgs pevent)
  227. {
  228. base.OnPaint(pevent);
  229. base.OnPaintBackground(pevent);
  230. Graphics g = pevent.Graphics;
  231. g.SmoothingMode = SmoothingMode.AntiAlias;
  232. g.InterpolationMode = InterpolationMode.HighQualityBicubic;
  233. Rectangle checkRect, textRect;
  234. CalculateRect(out checkRect, out textRect);
  235. if (Enabled == false)
  236. {
  237. _state = QQControlState.Disabled;
  238. }
  239. switch (_state)
  240. {
  241. case QQControlState.Highlight:
  242. case QQControlState.Down:
  243. DrawHighLightCheckRect(g, checkRect);
  244. break;
  245. case QQControlState.Disabled:
  246. DrawDisabledCheckRect(g, checkRect);
  247. break;
  248. default:
  249. DrawNormalCheckRect(g, checkRect);
  250. break;
  251. }
  252. Color textColor = (Enabled == true) ? ForeColor : SystemColors.GrayText;
  253. TextRenderer.DrawText(
  254. g,
  255. Text,
  256. Font,
  257. textRect,
  258. textColor,
  259. GetTextFormatFlags(TextAlign, RightToLeft == RightToLeft.Yes));
  260. }
  261. protected override void Dispose(bool disposing)
  262. {
  263. if (disposing)
  264. {
  265. if (_checkImg != null)
  266. {
  267. _checkImg.Dispose();
  268. }
  269. if (_defaultFont != null)
  270. {
  271. _defaultFont.Dispose();
  272. }
  273. if (_checkImgDel != null) {
  274. _checkImgDel.Dispose();
  275. }
  276. if (_checkImgSpecially != null)
  277. {
  278. _checkImgSpecially.Dispose();
  279. }
  280. }
  281. _checkImg = null;
  282. _checkImgDel = null;
  283. _checkImgSpecially = null;
  284. _defaultFont = null;
  285. base.Dispose(disposing);
  286. }
  287. #endregion
  288. #region Private
  289. private void DrawNormalCheckRect(Graphics g, Rectangle checkRect)
  290. {
  291. g.FillRectangle(Brushes.White, checkRect);
  292. using (Pen borderPen = new Pen(ColorTable.QQBorderColor))
  293. {
  294. g.DrawRectangle(borderPen, checkRect);
  295. }
  296. if (!Fourstates)
  297. {
  298. switch (this.CheckState)
  299. {
  300. case System.Windows.Forms.CheckState.Checked:
  301. g.DrawImage(_checkImg, checkRect, 0, 0, _checkImg.Width, _checkImg.Height, GraphicsUnit.Pixel);
  302. break;
  303. case System.Windows.Forms.CheckState.Indeterminate:
  304. g.DrawImage(_checkImgDel, checkRect, 0, 0, _checkImg.Width, _checkImg.Height, GraphicsUnit.Pixel);
  305. break;
  306. }
  307. }
  308. else {
  309. switch (this.CurrentCheckState)
  310. {
  311. case CheckStateEx.Checked:
  312. g.DrawImage(_checkImgSpecially, checkRect, 0, 0, _checkImg.Width, _checkImg.Height, GraphicsUnit.Pixel);
  313. break;
  314. case CheckStateEx.Indeterminate:
  315. g.DrawImage(_checkImgDel, checkRect, 0, 0, _checkImg.Width, _checkImg.Height, GraphicsUnit.Pixel);
  316. break;
  317. case CheckStateEx.Specially:
  318. g.DrawImage(_checkImg, checkRect, 0, 0, _checkImg.Width, _checkImg.Height, GraphicsUnit.Pixel);
  319. break;
  320. }
  321. }
  322. /* if (Checked)
  323. {
  324. g.DrawImage(_checkImg,checkRect, 0,0,_checkImg.Width, _checkImg.Height,GraphicsUnit.Pixel);
  325. }*/
  326. }
  327. private void DrawHighLightCheckRect(Graphics g, Rectangle checkRect)
  328. {
  329. DrawNormalCheckRect(g, checkRect);
  330. using (Pen p = new Pen(ColorTable.QQHighLightInnerColor))
  331. {
  332. g.DrawRectangle(p, checkRect);
  333. checkRect.Inflate(1, 1);
  334. p.Color = ColorTable.QQHighLightColor;
  335. g.DrawRectangle(p, checkRect);
  336. }
  337. }
  338. private void DrawDisabledCheckRect(Graphics g, Rectangle checkRect)
  339. {
  340. g.DrawRectangle(SystemPens.ControlDark, checkRect);
  341. if (!Fourstates)
  342. {
  343. switch (this.CheckState)
  344. {
  345. case System.Windows.Forms.CheckState.Checked:
  346. g.DrawImage(_checkImg, checkRect, 0, 0, _checkImg.Width, _checkImg.Height, GraphicsUnit.Pixel);
  347. break;
  348. case System.Windows.Forms.CheckState.Indeterminate:
  349. g.DrawImage(_checkImgDel, checkRect, 0, 0, _checkImg.Width, _checkImg.Height, GraphicsUnit.Pixel);
  350. break;
  351. }
  352. }
  353. else {
  354. switch (this.CurrentCheckState)
  355. {
  356. case CheckStateEx.Checked:
  357. g.DrawImage(_checkImgSpecially, checkRect, 0, 0, _checkImg.Width, _checkImg.Height, GraphicsUnit.Pixel);
  358. break;
  359. case CheckStateEx.Indeterminate:
  360. g.DrawImage(_checkImgDel, checkRect, 0, 0, _checkImg.Width, _checkImg.Height, GraphicsUnit.Pixel);
  361. break;
  362. case CheckStateEx.Specially:
  363. g.DrawImage(_checkImg, checkRect, 0, 0, _checkImg.Width, _checkImg.Height, GraphicsUnit.Pixel);
  364. break;
  365. }
  366. }
  367. /* if (Checked)
  368. {
  369. g.DrawImage(_checkImg,checkRect,0,0, _checkImg.Width,_checkImg.Height,GraphicsUnit.Pixel);
  370. }*/
  371. }
  372. private void SetStyles()
  373. {
  374. SetStyle(ControlStyles.UserPaint, true);
  375. SetStyle(ControlStyles.AllPaintingInWmPaint, true);
  376. SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
  377. SetStyle(ControlStyles.ResizeRedraw, true);
  378. SetStyle(ControlStyles.SupportsTransparentBackColor, true);
  379. UpdateStyles();
  380. }
  381. private void CalculateRect(out Rectangle checkRect, out Rectangle textRect)
  382. {
  383. checkRect = new Rectangle(
  384. 0, 0, CheckRectWidth, CheckRectWidth);
  385. textRect = Rectangle.Empty;
  386. bool bCheckAlignLeft = (int)(LeftAlignment & CheckAlign) != 0;
  387. bool bCheckAlignRight = (int)(RightAlignment & CheckAlign) != 0;
  388. bool bRightToLeft = (RightToLeft == RightToLeft.Yes);
  389. if ((bCheckAlignLeft && !bRightToLeft) ||
  390. (bCheckAlignRight && bRightToLeft))
  391. {
  392. switch (CheckAlign)
  393. {
  394. case ContentAlignment.TopRight:
  395. case ContentAlignment.TopLeft:
  396. checkRect.Y = 2;
  397. break;
  398. case ContentAlignment.MiddleRight:
  399. case ContentAlignment.MiddleLeft:
  400. checkRect.Y = (Height - CheckRectWidth) / 2;
  401. break;
  402. case ContentAlignment.BottomRight:
  403. case ContentAlignment.BottomLeft:
  404. checkRect.Y = Height - CheckRectWidth - 2;
  405. break;
  406. }
  407. checkRect.X = 1;
  408. textRect = new Rectangle(
  409. checkRect.Right + 2,
  410. 0,
  411. Width - checkRect.Right - 4,
  412. Height);
  413. }
  414. else if ((bCheckAlignRight && !bRightToLeft)
  415. || (bCheckAlignLeft && bRightToLeft))
  416. {
  417. switch (CheckAlign)
  418. {
  419. case ContentAlignment.TopLeft:
  420. case ContentAlignment.TopRight:
  421. checkRect.Y = 2;
  422. break;
  423. case ContentAlignment.MiddleLeft:
  424. case ContentAlignment.MiddleRight:
  425. checkRect.Y = (Height - CheckRectWidth) / 2;
  426. break;
  427. case ContentAlignment.BottomLeft:
  428. case ContentAlignment.BottomRight:
  429. checkRect.Y = Height - CheckRectWidth - 2;
  430. break;
  431. }
  432. checkRect.X = Width - CheckRectWidth - 1;
  433. textRect = new Rectangle(
  434. 2, 0, Width - CheckRectWidth - 6, Height);
  435. }
  436. else
  437. {
  438. switch (CheckAlign)
  439. {
  440. case ContentAlignment.TopCenter:
  441. checkRect.Y = 2;
  442. textRect.Y = checkRect.Bottom + 2;
  443. textRect.Height = Height - CheckRectWidth - 6;
  444. break;
  445. case ContentAlignment.MiddleCenter:
  446. checkRect.Y = (Height - CheckRectWidth) / 2;
  447. textRect.Y = 0;
  448. textRect.Height = Height;
  449. break;
  450. case ContentAlignment.BottomCenter:
  451. checkRect.Y = Height - CheckRectWidth - 2;
  452. textRect.Y = 0;
  453. textRect.Height = Height - CheckRectWidth - 6;
  454. break;
  455. }
  456. checkRect.X = (Width - CheckRectWidth) / 2;
  457. textRect.X = 2;
  458. textRect.Width = Width - 4;
  459. }
  460. }
  461. private static TextFormatFlags GetTextFormatFlags(ContentAlignment alignment, bool rightToleft)
  462. {
  463. TextFormatFlags flags = TextFormatFlags.WordBreak |
  464. TextFormatFlags.SingleLine;
  465. if (rightToleft)
  466. {
  467. flags |= TextFormatFlags.RightToLeft | TextFormatFlags.Right;
  468. }
  469. switch (alignment)
  470. {
  471. case ContentAlignment.BottomCenter:
  472. flags |= TextFormatFlags.Bottom | TextFormatFlags.HorizontalCenter;
  473. break;
  474. case ContentAlignment.BottomLeft:
  475. flags |= TextFormatFlags.Bottom | TextFormatFlags.Left;
  476. break;
  477. case ContentAlignment.BottomRight:
  478. flags |= TextFormatFlags.Bottom | TextFormatFlags.Right;
  479. break;
  480. case ContentAlignment.MiddleCenter:
  481. flags |= TextFormatFlags.HorizontalCenter |
  482. TextFormatFlags.VerticalCenter;
  483. break;
  484. case ContentAlignment.MiddleLeft:
  485. flags |= TextFormatFlags.VerticalCenter | TextFormatFlags.Left;
  486. break;
  487. case ContentAlignment.MiddleRight:
  488. flags |= TextFormatFlags.VerticalCenter | TextFormatFlags.Right;
  489. break;
  490. case ContentAlignment.TopCenter:
  491. flags |= TextFormatFlags.Top | TextFormatFlags.HorizontalCenter;
  492. break;
  493. case ContentAlignment.TopLeft:
  494. flags |= TextFormatFlags.Top | TextFormatFlags.Left;
  495. break;
  496. case ContentAlignment.TopRight:
  497. flags |= TextFormatFlags.Top | TextFormatFlags.Right;
  498. break;
  499. }
  500. return flags;
  501. }
  502. #endregion
  503. }
  504. /// <summary>
  505. /// CheckBox自定义状态
  506. /// </summary>
  507. public enum CheckStateEx
  508. {
  509. /// <summary>
  510. /// 勾选
  511. /// </summary>
  512. Checked = CheckState.Checked,
  513. /// <summary>
  514. /// 禁用
  515. /// </summary>
  516. Indeterminate = CheckState.Indeterminate,
  517. /// <summary>
  518. /// 未勾选
  519. /// </summary>
  520. Unchecked = CheckState.Unchecked,
  521. /// <summary>
  522. /// 特别状态
  523. /// </summary>
  524. Specially=100,
  525. }
  526. }