Progress.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. using InABox.Core;
  2. using System;
  3. using System.ComponentModel;
  4. using System.Linq;
  5. using System.Threading;
  6. using System.Windows.Media.Imaging;
  7. namespace InABox.WPF
  8. {
  9. public class ProgressSection
  10. {
  11. public ProgressSection(string message, Action action)
  12. {
  13. Message = message;
  14. Action = action;
  15. }
  16. public string Message { get; set; }
  17. public Action Action { get; set; }
  18. }
  19. public static class Progress
  20. {
  21. private static ProgressForm? form;
  22. public static BitmapImage? DisplayImage { get; set; }
  23. public static bool IsVisible => form != null;
  24. public static void ShowModal(params ProgressSection[] sections)
  25. {
  26. if (!sections.Any())
  27. return;
  28. var progress = new ProgressForm
  29. {
  30. DisplayImage = DisplayImage
  31. };
  32. progress.Activated += (_, args) =>
  33. {
  34. progress.Dispatcher.Invoke(() =>
  35. {
  36. foreach (var section in sections)
  37. {
  38. progress.Message = section.Message;
  39. section.Action();
  40. }
  41. progress.Close();
  42. });
  43. };
  44. progress.ShowActivated = true;
  45. progress.ShowDialog();
  46. }
  47. /// <summary>
  48. /// Shows progress dialog modally, with a cancel button.
  49. /// </summary>
  50. /// <param name="message"></param>
  51. /// <param name="cancelButtonText"></param>
  52. /// <param name="work"></param>
  53. /// <returns>Whether the progress was completed without cancelling.</returns>
  54. public static bool ShowModal(string message, string cancelButtonText, Action<IProgress<string>, CancellationToken> work)
  55. {
  56. var cancellationTokenSource = new CancellationTokenSource();
  57. var progress = new ProgressForm(cancelButtonText)
  58. {
  59. DisplayImage = DisplayImage
  60. };
  61. progress.Message = message;
  62. progress.Loaded += (_, args) =>
  63. {
  64. var worker = new BackgroundWorker();
  65. var update = new Progress<string>(data => progress.Message = data);
  66. progress.OnCancelled += () =>
  67. {
  68. cancellationTokenSource.Cancel();
  69. progress.Close();
  70. };
  71. worker.DoWork += (o, e) => work(update, cancellationTokenSource.Token);
  72. worker.RunWorkerCompleted +=
  73. (o, e) => progress.Close();
  74. worker.RunWorkerAsync();
  75. };
  76. progress.ShowDialog();
  77. return !cancellationTokenSource.IsCancellationRequested;
  78. }
  79. public static Result<T, string> ShowModal<T>(String message, Func<IProgress<string>, Result<T, string>> work)
  80. {
  81. Result<T, string> result = Result.Error("Incomplete");
  82. var progress = new ProgressForm
  83. {
  84. DisplayImage = DisplayImage
  85. };
  86. progress.Message = message;
  87. progress.Loaded += (_, args) =>
  88. {
  89. var worker = new BackgroundWorker();
  90. var update = new Progress<string>(data => progress.Message = data);
  91. progress.OnCancelled += () =>
  92. {
  93. worker.CancelAsync();
  94. };
  95. worker.DoWork += (o, e) =>
  96. {
  97. try
  98. {
  99. result = work(update);
  100. }
  101. catch (Exception ex)
  102. {
  103. result = Result.Error(ex.Message);
  104. }
  105. };
  106. worker.RunWorkerCompleted +=
  107. (o, e) => progress.Close();
  108. worker.RunWorkerAsync();
  109. };
  110. progress.ShowDialog();
  111. return result;
  112. }
  113. public static void ShowModal(string message, Action<IProgress<string>> work)
  114. {
  115. Exception? exception = null;
  116. var progress = new ProgressForm
  117. {
  118. DisplayImage = DisplayImage
  119. };
  120. progress.Message = message;
  121. progress.Loaded += (_, args) =>
  122. {
  123. var worker = new BackgroundWorker();
  124. var update = new Progress<string>(data => progress.Message = data);
  125. progress.OnCancelled += () =>
  126. {
  127. worker.CancelAsync();
  128. };
  129. worker.DoWork += (o, e) =>
  130. {
  131. try
  132. {
  133. work(update);
  134. }
  135. catch (Exception ex)
  136. {
  137. exception = ex;
  138. }
  139. };
  140. worker.RunWorkerCompleted +=
  141. (o, e) => progress.Close();
  142. worker.RunWorkerAsync();
  143. };
  144. progress.ShowDialog();
  145. if(exception is not null)
  146. {
  147. throw exception;
  148. }
  149. }
  150. public static void Show(string message)
  151. {
  152. if (form == null)
  153. {
  154. form = new ProgressForm
  155. {
  156. DisplayImage = DisplayImage
  157. };
  158. form.Show();
  159. }
  160. form.UpdateWindow(message);
  161. }
  162. public static void SetMessage(string message)
  163. {
  164. form?.UpdateWindow(message);
  165. }
  166. public static void Close()
  167. {
  168. form?.CloseWindow();
  169. form = null;
  170. }
  171. }
  172. }