UIMarquee.cs 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. using System;
  2. using System.Drawing;
  3. using System.Drawing.Drawing2D;
  4. using System.Windows.Forms;
  5. using Microsoft.Drawing;
  6. using Microsoft.Windows.Forms.Animate;
  7. namespace Microsoft.Windows.Forms
  8. {
  9. /// <summary>
  10. /// 跑马灯控件
  11. /// </summary>
  12. public class UIMarquee : UIControl
  13. {
  14. private const int DEFAULT_FRAME_INTERVAL = 10; //定时器间隔(毫秒)
  15. private Timer m_FrameTimer = new Timer(); //动画定时器
  16. private UILinearAnimation m_Animation = new UILinearAnimation(); //动画对象
  17. private static readonly object EVENT_TIMER_TICK = new object();
  18. /// <summary>
  19. /// 定时器滴答事件
  20. /// </summary>
  21. public event EventHandler TimerTick
  22. {
  23. add
  24. {
  25. base.Events.AddHandler(EVENT_TIMER_TICK, value);
  26. }
  27. remove
  28. {
  29. base.Events.RemoveHandler(EVENT_TIMER_TICK, value);
  30. }
  31. }
  32. /// <summary>
  33. /// 触发定时器滴答事件
  34. /// </summary>
  35. /// <param name="e">事件数据</param>
  36. protected virtual void OnTimerTick(EventArgs e)
  37. {
  38. EventHandler handler = base.Events[EVENT_TIMER_TICK] as EventHandler;
  39. if (handler != null)
  40. handler(this.m_FrameTimer, e);
  41. }
  42. private Color m_ProgressColor = DefaultTheme.LightTransparent;
  43. /// <summary>
  44. /// 获取或设置进度条颜色
  45. /// </summary>
  46. public virtual Color ProgressColor
  47. {
  48. get
  49. {
  50. return this.m_ProgressColor;
  51. }
  52. set
  53. {
  54. if (value != this.m_ProgressColor)
  55. {
  56. this.m_ProgressColor = value;
  57. this.Invalidate();
  58. }
  59. }
  60. }
  61. private Color m_BorderColor = DefaultTheme.LightLightTransparent;
  62. /// <summary>
  63. /// 获取或设置进度条边框颜色
  64. /// </summary>
  65. public virtual Color BorderColor
  66. {
  67. get
  68. {
  69. return this.m_BorderColor;
  70. }
  71. set
  72. {
  73. if (value != this.m_BorderColor)
  74. {
  75. this.m_BorderColor = value;
  76. this.Invalidate();
  77. }
  78. }
  79. }
  80. private int m_ProgressLengthReal;//真实长度
  81. private float m_ProgressLength = 0.2F;
  82. /// <summary>
  83. /// 获取或设置进度深色长度0-1f
  84. /// </summary>
  85. public float ProgressLength
  86. {
  87. get
  88. {
  89. return this.m_ProgressLength;
  90. }
  91. set
  92. {
  93. if (value == this.m_ProgressLength)
  94. return;
  95. this.m_ProgressLength = value;
  96. this.Invalidate();
  97. }
  98. }
  99. /// <summary>
  100. /// 获取或设置动画是否停止
  101. /// </summary>
  102. public bool Stopped
  103. {
  104. get { return this.m_FrameTimer.Enabled; }
  105. set
  106. {
  107. if (value != this.m_FrameTimer.Enabled)
  108. {
  109. if (value)
  110. this.Start();
  111. else
  112. this.Stop();
  113. }
  114. }
  115. }
  116. /// <summary>
  117. /// 获取或设置动画间隔,默认为2000ms
  118. /// </summary>
  119. public int AnimationSpan
  120. {
  121. get { return this.m_Animation.Span; }
  122. set { this.m_Animation.Span = value; }
  123. }
  124. /// <summary>
  125. /// 构造函数
  126. /// </summary>
  127. public UIMarquee()
  128. {
  129. this.BackColor = DefaultTheme.DarkDarkTransparent;
  130. this.m_FrameTimer.Interval = DEFAULT_FRAME_INTERVAL;
  131. this.m_FrameTimer.Tick += (sender, e) =>
  132. {
  133. this.OnTimerTick(EventArgs.Empty);
  134. this.Invalidate();
  135. if (this.m_Animation.Stopped)
  136. this.m_Animation.Next();
  137. };
  138. this.m_Animation.Span = 2000;
  139. this.ResetAnimation();
  140. }
  141. /// <summary>
  142. /// 重置动画参数
  143. /// </summary>
  144. protected virtual void ResetAnimation()
  145. {
  146. Rectangle rect = RectangleEx.Subtract(this.ClientRectangle, this.Padding);
  147. Rectangle rcContent = RectangleEx.Subtract(rect, new Padding(1));
  148. int width = rcContent.Width;
  149. this.m_Animation.From = rcContent.Left;
  150. this.m_ProgressLengthReal = (int)(width * this.m_ProgressLength);
  151. this.m_Animation.To = width + this.m_ProgressLengthReal + 1;//要多一个像素
  152. }
  153. /// <summary>
  154. /// 触发大小改变事件
  155. /// </summary>
  156. /// <param name="e">数据</param>
  157. protected override void OnSizeChanged(EventArgs e)
  158. {
  159. base.OnSizeChanged(e);
  160. this.ResetAnimation();
  161. }
  162. /// <summary>
  163. /// 渲染控件
  164. /// </summary>
  165. /// <param name="e">数据</param>
  166. protected override void RenderSelf(PaintEventArgs e)
  167. {
  168. //准备
  169. Graphics g = e.Graphics;
  170. Rectangle rect = RectangleEx.Subtract(this.ClientRectangle, this.Padding);
  171. Rectangle rcContent = RectangleEx.Subtract(rect, new Padding(1));
  172. int left = rcContent.Left;
  173. int top = rcContent.Top;
  174. int height = rcContent.Height;
  175. int position = (int)this.m_Animation.Current;
  176. Rectangle rcMiddle = new Rectangle(position - this.m_ProgressLengthReal, top, this.m_ProgressLengthReal, height);
  177. Rectangle rcLeft = new Rectangle(left, top, rcMiddle.Left - left, height);
  178. Rectangle rcRight = new Rectangle(rcMiddle.Right, top, rect.Right - 1 - rcMiddle.Right, height);
  179. //渲染进度
  180. using (new ClipGraphics(g, rcContent, CombineMode.Intersect))
  181. {
  182. if (RectangleEx.IsVisible(rcLeft))
  183. {
  184. this.Sprite.BorderVisibleStyle = BorderVisibleStyle.None;
  185. this.Sprite.BackColor = this.BackColor;
  186. this.Sprite.State = this.State;
  187. this.Sprite.BeginRender(g);
  188. this.Sprite.RenderBackColor(rcLeft);
  189. this.Sprite.EndRender();
  190. }
  191. if (RectangleEx.IsVisible(rcMiddle))
  192. {
  193. this.Sprite.BorderVisibleStyle = BorderVisibleStyle.None;
  194. this.Sprite.BackColor = this.ProgressColor;
  195. this.Sprite.State = this.State;
  196. this.Sprite.BeginRender(g);
  197. this.Sprite.RenderBackColor(rcMiddle);
  198. this.Sprite.EndRender();
  199. }
  200. if (RectangleEx.IsVisible(rcRight))
  201. {
  202. this.Sprite.BorderVisibleStyle = BorderVisibleStyle.None;
  203. this.Sprite.BackColor = this.BackColor;
  204. this.Sprite.State = this.State;
  205. this.Sprite.BeginRender(g);
  206. this.Sprite.RenderBackColor(rcRight);
  207. this.Sprite.EndRender();
  208. }
  209. }
  210. //渲染边框
  211. this.Sprite.BorderVisibleStyle = BorderVisibleStyle.All;
  212. this.Sprite.BorderColor = this.BorderColor;
  213. this.Sprite.BeginRender(g);
  214. this.Sprite.RenderBorder(rect);
  215. this.Sprite.EndRender();
  216. }
  217. /// <summary>
  218. /// 开始动画
  219. /// </summary>
  220. public virtual void Start()
  221. {
  222. this.m_Animation.Next();
  223. this.m_FrameTimer.Start();
  224. }
  225. /// <summary>
  226. /// 停止动画
  227. /// </summary>
  228. public virtual void Stop()
  229. {
  230. this.m_Animation.Stop();
  231. this.m_FrameTimer.Stop();
  232. this.Invalidate();
  233. }
  234. /// <summary>
  235. /// 释放资源
  236. /// </summary>
  237. /// <param name="disposing">释放托管资源为true,否则为false</param>
  238. protected override void Dispose(bool disposing)
  239. {
  240. if (this.m_FrameTimer != null)
  241. {
  242. this.m_FrameTimer.Dispose();
  243. this.m_FrameTimer = null;
  244. }
  245. if (this.m_Animation != null)
  246. {
  247. this.m_Animation.Dispose();
  248. this.m_Animation = null;
  249. }
  250. base.Dispose(disposing);
  251. }
  252. }
  253. }