Switch.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. using ImpulseVision;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.ComponentModel;
  5. using System.Data;
  6. using System.Drawing;
  7. using System.Drawing.Drawing2D;
  8. using System.Linq;
  9. using System.Text;
  10. using System.Threading.Tasks;
  11. using System.Windows.Forms;
  12. using static System.Net.Mime.MediaTypeNames;
  13. using static System.Windows.Forms.VisualStyles.VisualStyleElement.TextBox;
  14. using System.Windows.Forms.Design;
  15. namespace ImpulseVision
  16. {
  17. [Designer(typeof(ControlDesignerEx))] // ControlDesignerEx Добавляем для ограничения изменения размеров
  18. [DefaultEvent("CheckedChanged")]
  19. public class EgoldsToggleSwitch : Control
  20. {
  21. #region -- Свойства --
  22. public bool Checked
  23. {
  24. get => _checked;
  25. set
  26. {
  27. _checked = value;
  28. SwitchToggle();
  29. UpdateSize();
  30. UpdateStructures();
  31. }
  32. }
  33. private bool _checked = false;
  34. public Color BackColorON { get; set; } = FlatColors.GreenDark;
  35. public Color BackColorOFF { get; set; } = FlatColors.Red;
  36. public override string Text
  37. {
  38. get => text;
  39. set
  40. {
  41. text = value;
  42. UpdateSize();
  43. UpdateStructures();
  44. }
  45. }
  46. private string text = string.Empty;
  47. public string TextOnChecked
  48. {
  49. get => _textOnChecked;
  50. set
  51. {
  52. _textOnChecked = value;
  53. UpdateSize();
  54. UpdateStructures();
  55. }
  56. }
  57. private string _textOnChecked = string.Empty;
  58. #endregion
  59. #region -- Переменные --
  60. private Rectangle rectToggleHolder;
  61. private int ToogleSwitchWidth = 40;
  62. private Rectangle rectText;
  63. private int TogglePosX_ON;
  64. private int TogglePosX_OFF;
  65. private Animation ToggleAnim = new Animation();
  66. private StringFormat SF = new StringFormat();
  67. #endregion
  68. #region -- События --
  69. [Description("Возникает при каждом изменении свойства Checked")]
  70. public event OnCheckedChangedHandler CheckedChanged;
  71. public delegate void OnCheckedChangedHandler(object sender);
  72. #endregion
  73. public EgoldsToggleSwitch()
  74. {
  75. SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.SupportsTransparentBackColor | ControlStyles.UserPaint, true);
  76. DoubleBuffered = true;
  77. SF.Alignment = StringAlignment.Near;
  78. SF.LineAlignment = StringAlignment.Center;
  79. Font = new Font("Verdana", 9F, FontStyle.Regular);
  80. BackColor = Color.White;
  81. Cursor = Cursors.Hand;
  82. Size = new Size(ToogleSwitchWidth, 15);
  83. UpdateSize();
  84. UpdateStructures();
  85. }
  86. protected override void OnCreateControl()
  87. {
  88. base.OnCreateControl();
  89. UpdateStructures();
  90. ToggleAnim.Value = Checked == true ? TogglePosX_ON : TogglePosX_OFF;
  91. }
  92. protected override void OnPaint(PaintEventArgs e)
  93. {
  94. base.OnPaint(e);
  95. Graphics graph = e.Graphics;
  96. graph.SmoothingMode = SmoothingMode.HighQuality;
  97. graph.Clear(Parent.BackColor);
  98. Pen penToggleHolder = new Pen(FlatColors.GrayDark, 1.55f);
  99. Pen penToggle = new Pen(FlatColors.GrayDark, 3);
  100. GraphicsPath gpathToggle = Drawer.RoundedRectangle(rectToggleHolder, rectToggleHolder.Height);
  101. Rectangle rectToggle = new Rectangle((int)ToggleAnim.Value, rectToggleHolder.Y, rectToggleHolder.Height, rectToggleHolder.Height);
  102. graph.DrawPath(penToggleHolder, gpathToggle);
  103. if (Checked == true)
  104. {
  105. if (Animator.IsWork == false)
  106. rectToggle.Location = new Point(TogglePosX_ON, rectToggleHolder.Y);
  107. graph.FillPath(new SolidBrush(BackColorON), gpathToggle);
  108. }
  109. else
  110. {
  111. if (Animator.IsWork == false)
  112. rectToggle.Location = new Point(TogglePosX_OFF, rectToggleHolder.Y);
  113. graph.FillPath(new SolidBrush(BackColorOFF), gpathToggle);
  114. }
  115. graph.DrawEllipse(penToggle, rectToggle);
  116. graph.FillEllipse(new SolidBrush(BackColor), rectToggle);
  117. string drawText = Text;
  118. if (!string.IsNullOrEmpty(TextOnChecked) && Checked)
  119. drawText = TextOnChecked;
  120. graph.DrawString(drawText, Font, new SolidBrush(ForeColor), rectText, SF);
  121. }
  122. protected override void OnMouseDown(MouseEventArgs e)
  123. {
  124. base.OnMouseDown(e);
  125. Checked = !Checked;
  126. }
  127. private void SwitchToggle()
  128. {
  129. if (Checked == true)
  130. {
  131. ToggleAnim = new Animation("Toggle_" + Handle, Invalidate, ToggleAnim.Value, TogglePosX_ON);
  132. }
  133. else
  134. {
  135. ToggleAnim = new Animation("Toggle_" + Handle, Invalidate, ToggleAnim.Value, TogglePosX_OFF);
  136. }
  137. ToggleAnim.StepDivider = 8;
  138. Animator.Request(ToggleAnim, true);
  139. CheckedChanged?.Invoke(this);
  140. }
  141. private void UpdateSize()
  142. {
  143. string drawText = Text;
  144. if (!string.IsNullOrEmpty(TextOnChecked) && Checked) drawText = TextOnChecked;
  145. Size size = TextRenderer.MeasureText(drawText, Font);
  146. Width = ToogleSwitchWidth + size.Width + 3;
  147. }
  148. private void UpdateStructures()
  149. {
  150. rectToggleHolder = new Rectangle(1, 1, ToogleSwitchWidth - 3, Height - 3);
  151. int rectTextWidth = Width - ToogleSwitchWidth - 3;
  152. int rectTextX = rectToggleHolder.Right + 6;
  153. rectText = new Rectangle(rectTextX, rectToggleHolder.Y, rectTextWidth, rectToggleHolder.Height);
  154. TogglePosX_OFF = rectToggleHolder.X;
  155. TogglePosX_ON = rectToggleHolder.Right - rectToggleHolder.Height;
  156. }
  157. /// <summary>
  158. /// В этом классе переопределяем SelectionRules, и даем возможность только изменять ширину и перемещать объект
  159. /// </summary>
  160. class ControlDesignerEx : ControlDesigner
  161. {
  162. public override SelectionRules SelectionRules
  163. {
  164. get
  165. {
  166. SelectionRules sr = SelectionRules.Moveable | SelectionRules.Visible;
  167. return sr;
  168. }
  169. }
  170. }
  171. }
  172. }