You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

401 lines
13 KiB

1 month ago
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Drawing;
  5. using System.Data;
  6. using System.Drawing.Drawing2D;
  7. using System.Linq;
  8. using System.Text;
  9. using System.Windows.Forms;
  10. namespace Customize.Controls
  11. {
  12. [DefaultEvent("Click")]
  13. [ToolboxBitmap(typeof(Button))]
  14. public partial class CcButton : Button
  15. {
  16. #region attribute
  17. /// <summary>
  18. /// 圆角值
  19. /// </summary>
  20. private int _CornerRadius = 2;
  21. /// <summary>
  22. /// 内容边距间隔
  23. /// </summary>
  24. private int _Margin = 4;
  25. /// <summary>
  26. /// 图标大小
  27. /// </summary>
  28. private Size _ImageSize = new Size(16, 16);
  29. /// <summary>
  30. /// 控件的状态
  31. /// </summary>
  32. private EnumControlState _ControlState;
  33. #endregion
  34. #region Initializes
  35. /// <summary>
  36. /// (构造函数).Initializes a new instance of the <see cref="TXButton"/> class.
  37. /// </summary>
  38. /// User:Ryan CreateTime:2011-08-01 16:15.
  39. public CcButton()
  40. {
  41. this.SetStyle(ControlStyles.UserPaint, true);
  42. this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
  43. this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
  44. this.SetStyle(ControlStyles.DoubleBuffer, true);
  45. this.SetStyle(ControlStyles.ResizeRedraw, true);
  46. this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
  47. //this.UpdateStyles();
  48. this._ControlState = EnumControlState.Default;
  49. base.TextImageRelation = TextImageRelation.ImageBeforeText;
  50. this.Size = new Size(100, 30);
  51. this.ResetRegion();
  52. }
  53. #endregion
  54. #region Properties
  55. [Category("CCProperties")]
  56. [Description("圆角的半径值")]
  57. [DefaultValue(2)]
  58. public int CornerRadius
  59. {
  60. get { return this._CornerRadius; }
  61. set
  62. {
  63. this._CornerRadius = value;
  64. this.Invalidate();
  65. }
  66. }
  67. [Category("CCProperties")]
  68. [Browsable(true)]
  69. [Description("图标大小")]
  70. [DefaultValue(typeof(Size), "16,16")]
  71. public Size ImageSize
  72. {
  73. get { return this._ImageSize; }
  74. set { this._ImageSize = value; this.Invalidate(); }
  75. }
  76. [Category("CCProperties")]
  77. [Browsable(true)]
  78. [Description("图标")]
  79. public new Image Image
  80. {
  81. get { return base.Image; }
  82. set
  83. {
  84. base.Image = value;
  85. this.Invalidate();
  86. }
  87. }
  88. [Category("CCProperties")]
  89. [Browsable(true)]
  90. [DefaultValue(typeof(TextImageRelation), "ImageBeforeText")]
  91. public new TextImageRelation TextImageRelation
  92. {
  93. get { return base.TextImageRelation; }
  94. set { base.TextImageRelation = value; }
  95. }
  96. [Browsable(false)]
  97. public new Color BackColor
  98. {
  99. get { return base.BackColor; }
  100. }
  101. [Browsable(false)]
  102. public new ContentAlignment TextAlign
  103. {
  104. get { return base.TextAlign; }
  105. }
  106. [Browsable(false)]
  107. public new ContentAlignment ImageAlign
  108. {
  109. get { return base.ImageAlign; }
  110. }
  111. #endregion
  112. #region Override methods
  113. protected override void OnMouseEnter(EventArgs e)
  114. {
  115. base.OnMouseEnter(e);
  116. this._ControlState = EnumControlState.HeightLight;
  117. this.Invalidate();
  118. }
  119. protected override void OnMouseDown(MouseEventArgs e)
  120. {
  121. base.OnMouseDown(e);
  122. if (e.Button == MouseButtons.Left)
  123. {
  124. this._ControlState = EnumControlState.Focused;
  125. this.Invalidate();
  126. }
  127. }
  128. protected override void OnMouseLeave(EventArgs e)
  129. {
  130. base.OnMouseLeave(e);
  131. this._ControlState = EnumControlState.Default;
  132. this.Invalidate();
  133. }
  134. protected override void OnMouseUp(MouseEventArgs e)
  135. {
  136. base.OnMouseUp(e);
  137. if (e.Button == MouseButtons.Left)
  138. {
  139. this._ControlState = EnumControlState.HeightLight;
  140. this.Invalidate();
  141. }
  142. }
  143. protected override void OnKeyDown(KeyEventArgs e)
  144. {
  145. base.OnKeyDown(e);
  146. if (e.KeyCode == Keys.Space)
  147. {
  148. this._ControlState = EnumControlState.Focused;
  149. this.Invalidate();
  150. }
  151. }
  152. protected override void OnKeyUp(KeyEventArgs e)
  153. {
  154. base.OnKeyUp(e);
  155. if (e.KeyCode == Keys.Space)
  156. {
  157. this._ControlState = EnumControlState.Default;
  158. this.Invalidate();
  159. this.OnClick(e);
  160. }
  161. }
  162. protected override void OnGotFocus(EventArgs e)
  163. {
  164. base.OnGotFocus(e);
  165. this._ControlState = EnumControlState.HeightLight;
  166. this.Invalidate();
  167. }
  168. protected override void OnLostFocus(EventArgs e)
  169. {
  170. base.OnLostFocus(e);
  171. this._ControlState = EnumControlState.Default;
  172. this.Invalidate();
  173. }
  174. protected override void OnResize(EventArgs e)
  175. {
  176. base.OnResize(e);
  177. this.ResetRegion();
  178. }
  179. protected override void OnCreateControl()
  180. {
  181. base.OnCreateControl();
  182. this.ResetRegion();
  183. }
  184. protected override void OnPaint(PaintEventArgs e)
  185. {
  186. base.OnPaint(e);
  187. base.OnPaintBackground(e);
  188. this.ResetRegion();
  189. Graphics g = e.Graphics;
  190. this.DrawBackGround(g);
  191. this.DrawContent(g);
  192. }
  193. #endregion
  194. #region Private methods
  195. #region DrawBackGround
  196. /// <summary>
  197. /// 绘制背景和边框等
  198. /// </summary>
  199. /// <param name="g">The Graphics.</param>
  200. private void DrawBackGround(Graphics g)
  201. {
  202. GDIHelper.InitializeGraphics(g);
  203. Rectangle rect = new Rectangle(1, 1, this.Width - 3, this.Height - 3);
  204. RoundRectangle roundRect = new RoundRectangle(rect, new CornerRadius(this._CornerRadius));
  205. switch (this._ControlState)
  206. {
  207. case EnumControlState.Default:
  208. if (this.FlatStyle != FlatStyle.Flat)
  209. {
  210. GDIHelper.FillRectangle(g, roundRect, SkinManager.CurrentSkin.DefaultControlColor);
  211. GDIHelper.DrawPathBorder(g, roundRect, SkinManager.CurrentSkin.BorderColor);
  212. }
  213. break;
  214. case EnumControlState.HeightLight:
  215. GDIHelper.FillRectangle(g, roundRect, SkinManager.CurrentSkin.HeightLightControlColor);
  216. GDIHelper.DrawPathBorder(g, roundRect);
  217. break;
  218. case EnumControlState.Focused:
  219. GDIHelper.FillRectangle(g, roundRect, SkinManager.CurrentSkin.FocusedControlColor);
  220. GDIHelper.DrawPathBorder(g, roundRect);
  221. GDIHelper.DrawPathInnerBorder(g, roundRect);
  222. break;
  223. }
  224. }
  225. #endregion
  226. #region DrawContent
  227. /// <summary>
  228. /// 绘制按钮的内容:图标和文字
  229. /// </summary>
  230. /// <param name="g">The Graphics.</param>
  231. private void DrawContent(Graphics g)
  232. {
  233. Rectangle imageRect;
  234. Rectangle textRect;
  235. this.CalculateRect(out imageRect, out textRect);
  236. if (this.Image != null)
  237. {
  238. g.DrawImage(this.Image, imageRect, 0, 0, this._ImageSize.Width, this._ImageSize.Height, GraphicsUnit.Pixel);
  239. }
  240. Color forceColor = this.Enabled ? this.ForeColor : SkinManager.CurrentSkin.UselessColor;
  241. TextRenderer.DrawText(g, this.Text, this.Font, textRect, forceColor, TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);
  242. }
  243. #endregion
  244. #region CalculateRect
  245. /// <summary>
  246. /// 计算图标和文字的区域
  247. /// </summary>
  248. /// <param name="imageRect">The image rect.</param>
  249. /// <param name="textRect">The text rect.</param>
  250. private void CalculateRect(out Rectangle imageRect, out Rectangle textRect)
  251. {
  252. imageRect = Rectangle.Empty;
  253. textRect = Rectangle.Empty;
  254. if (Image == null)
  255. {
  256. textRect = new Rectangle(
  257. this._Margin,
  258. this._Margin,
  259. this.Width - this._Margin * 2,
  260. this.Height - this._Margin * 2);
  261. return;
  262. }
  263. Size textSize = TextRenderer.MeasureText(this.Text, this.Font);
  264. int textMaxWidth = this.Width - this._ImageSize.Width - this._Margin * 3;
  265. int textWidth = textSize.Width >= textMaxWidth ? textMaxWidth : textSize.Width;
  266. int contentWidth = this._Margin + this._ImageSize.Width + textWidth;
  267. switch (TextImageRelation)
  268. {
  269. case TextImageRelation.Overlay:
  270. imageRect = new Rectangle(
  271. this._Margin,
  272. (this.Height - this._ImageSize.Height) / 2,
  273. this._ImageSize.Width,
  274. this._ImageSize.Height);
  275. textRect = new Rectangle(
  276. this._Margin,
  277. this._Margin,
  278. this.Width - this._Margin * 2,
  279. this.Height);
  280. break;
  281. case TextImageRelation.ImageAboveText:
  282. imageRect = new Rectangle(
  283. (this.Width - this._ImageSize.Width) / 2,
  284. this._Margin,
  285. this._ImageSize.Width,
  286. this._ImageSize.Height);
  287. textRect = new Rectangle(
  288. this._Margin,
  289. imageRect.Bottom,
  290. this.Width - this._Margin * 2,
  291. this.Height - imageRect.Bottom - this._Margin);
  292. break;
  293. case TextImageRelation.ImageBeforeText:
  294. imageRect = new Rectangle(
  295. (this.Width - contentWidth) / 2,
  296. (this.Height - this._ImageSize.Height) / 2,
  297. this._ImageSize.Width,
  298. this._ImageSize.Height);
  299. textRect = new Rectangle(
  300. imageRect.Right + this._Margin,
  301. this._Margin,
  302. textWidth,
  303. this.Height - this._Margin * 2);
  304. break;
  305. case TextImageRelation.TextAboveImage:
  306. imageRect = new Rectangle(
  307. (this.Width - this._ImageSize.Width) / 2,
  308. this.Height - this._ImageSize.Height - this._Margin,
  309. this._ImageSize.Width,
  310. this._ImageSize.Height);
  311. textRect = new Rectangle(
  312. this._Margin,
  313. this._Margin,
  314. this.Width - this._Margin * 2,
  315. this.Height - imageRect.Y - this._Margin);
  316. break;
  317. case TextImageRelation.TextBeforeImage:
  318. imageRect = new Rectangle(
  319. (this.Width + contentWidth) / 2 - this._ImageSize.Width,
  320. (this.Height - this._ImageSize.Height) / 2,
  321. this._ImageSize.Width,
  322. this._ImageSize.Height);
  323. textRect = new Rectangle(
  324. (this.Width - contentWidth) / 2,
  325. this._Margin,
  326. textWidth,
  327. this.Height - this._Margin * 2);
  328. break;
  329. }
  330. if (RightToLeft == RightToLeft.Yes)
  331. {
  332. imageRect.X = this.Width - imageRect.Right;
  333. textRect.X = this.Width - textRect.Right;
  334. }
  335. }
  336. #endregion
  337. #region ResetRegion
  338. private void ResetRegion()
  339. {
  340. if (this._CornerRadius > 0)
  341. {
  342. Rectangle rect = new Rectangle(Point.Empty, this.Size);
  343. //rect.Height--;
  344. //rect.Width--;
  345. RoundRectangle roundRect = new RoundRectangle(rect, new CornerRadius(this._CornerRadius));
  346. if (this.Region != null)
  347. {
  348. this.Region.Dispose();
  349. }
  350. this.Region = new Region(roundRect.ToGraphicsBezierPath());
  351. }
  352. }
  353. #endregion
  354. #endregion
  355. }
  356. }