Progress.cs 4.5 KB

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