LoadingWrap.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. using BeatLyrics.Tool.Properties;
  2. using System;
  3. using System.Drawing;
  4. using System.Threading;
  5. using System.Threading.Tasks;
  6. using System.Windows.Forms;
  7. namespace BeatLyrics.Tool.Utils
  8. {
  9. public static class LoadingWrap
  10. {
  11. private static readonly Image LoadingImage = Resources.loading;
  12. public static IDisposable ShowLoading(this Form control, string text, int delayMs = 500, int fadingMs = 500)
  13. {
  14. if (false == control.InvokeRequired)
  15. throw new InvalidOperationException("需要从非界面线程调用此方法");
  16. Form form = null;
  17. void CreateControl()
  18. {
  19. form = new Form
  20. {
  21. FormBorderStyle = FormBorderStyle.None
  22. ,
  23. Width = 320
  24. ,
  25. Height = 64
  26. ,
  27. StartPosition = FormStartPosition.CenterParent
  28. ,
  29. ShowInTaskbar = false
  30. ,
  31. Opacity = 0
  32. };
  33. var panel = new Panel { BorderStyle = BorderStyle.FixedSingle, Dock = DockStyle.Fill, };
  34. form.Controls.Add(panel);
  35. var size = Math.Min(form.Width, form.Height);
  36. panel.Controls.Add(new Label
  37. {
  38. Text = text,
  39. Dock = DockStyle.Fill,
  40. TextAlign = ContentAlignment.MiddleLeft,
  41. });
  42. panel.Controls.Add(new PictureBox
  43. {
  44. Dock = DockStyle.Left
  45. ,
  46. Height = size
  47. ,
  48. Width = size
  49. ,
  50. SizeMode = PictureBoxSizeMode.Zoom
  51. ,
  52. Image = LoadingImage
  53. });
  54. panel.Controls.Add(new Panel { Height = 20, Dock = DockStyle.Top });
  55. panel.Controls.Add(new Panel { Height = 20, Dock = DockStyle.Bottom });
  56. }
  57. const int stepMs = 100;
  58. var closed = false;
  59. var step = 1d / ((double)fadingMs / stepMs);
  60. void ShowInvisibleForm()
  61. {
  62. control.Invoke(new Action(() => form.ShowDialog(control)));
  63. }
  64. void DelayAndFadeIn()
  65. {
  66. Thread.Sleep(delayMs);
  67. if (closed)
  68. return;
  69. var alpha = 0d;
  70. while (false == closed && alpha < 1)
  71. {
  72. alpha += step;
  73. if (alpha > 1)
  74. alpha = 1;
  75. var localVar = alpha;
  76. control.Invoke(new Action(() => form.Opacity = localVar));
  77. Thread.Sleep(stepMs);
  78. }
  79. }
  80. void FadeOutAndClose()
  81. {
  82. closed = true;
  83. var alpha = 0d;
  84. control.Invoke(new Action(() => alpha = form.Opacity));
  85. while (alpha > 0)
  86. {
  87. alpha -= step;
  88. if (alpha < 0)
  89. alpha = 0;
  90. control.Invoke(new Action(() => form.Opacity = alpha));
  91. Thread.Sleep(stepMs);
  92. }
  93. control.Invoke(new Action(() => form.Close()));
  94. }
  95. control.Invoke(new Action(CreateControl));
  96. Task.Factory.StartNew(ShowInvisibleForm);
  97. Task.Factory.StartNew(DelayAndFadeIn);
  98. return new Disposable(FadeOutAndClose);
  99. }
  100. private class Disposable : IDisposable
  101. {
  102. private readonly Action _action;
  103. public Disposable(Action action)
  104. {
  105. _action = action;
  106. }
  107. public void Dispose()
  108. {
  109. _action();
  110. }
  111. }
  112. }
  113. }