You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

160 lines
6.7 KiB

  1. using BPA.UIControl.Commons;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Threading.Tasks;
  5. using System.Windows;
  6. using System.Windows.Data;
  7. using static BPA.UIControl.DialogContainer;
  8. namespace BPA.UIControl
  9. {
  10. /// <summary>
  11. /// 对话框操作类
  12. /// </summary>
  13. public class Dialog
  14. {
  15. /// <summary>
  16. /// 对话框集合
  17. /// </summary>
  18. internal static Dictionary<string, DialogContainer> Dialogs { get; private set; } = new Dictionary<string, DialogContainer>();
  19. private static IDialogDataContextConfiguration dataContextConfiguration = new DialogDataContextConfiguration();
  20. /// <summary>
  21. /// 配置对话框 DataContext 操作逻辑
  22. /// </summary>
  23. /// <param name="configuration">配置逻辑</param>
  24. public static void ConfigureDataContextAction(IDialogDataContextConfiguration configuration)
  25. {
  26. dataContextConfiguration = configuration;
  27. }
  28. /// <summary>
  29. /// 添加对话框
  30. /// </summary>
  31. /// <param name="identifier">标识</param>
  32. /// <param name="dialog">对话框</param>
  33. internal static void AddDialogContainer(string identifier, DialogContainer dialog)
  34. {
  35. if (Dialogs.ContainsKey(identifier))
  36. {
  37. _ = Dialogs.Remove(identifier);
  38. }
  39. Dialogs.Add(identifier, dialog);
  40. }
  41. private static async Task<object> ShowInternal(DialogContainer dialog, object content, object parameters, string title, Action<DialogContainer> openHandler, Action<DialogContainer, object> closeHandle, bool? showCloseButton)
  42. {
  43. dialog.Dispatcher.VerifyAccess();
  44. if (!dataContextConfiguration.OnOpenAction(dialog, content, parameters))
  45. {
  46. dialog.Title = title;
  47. }
  48. dialog.DialogContent = content;
  49. dialog.IsShowCloseButton = showCloseButton == null ? dialog.IsShowCloseButton : showCloseButton.Value;
  50. dialog.BeforeOpenHandler = openHandler;
  51. dialog.AfterCloseHandler = closeHandle;
  52. DialogContainer.OpenDialogCommand.Execute(parameters, dialog);
  53. var taskCompletionSource = new TaskCompletionSource<object>();
  54. dialog.Tag = taskCompletionSource;
  55. dialog.AfterClose += OnDialogClosed;
  56. var result = await taskCompletionSource.Task;
  57. dialog.AfterClose -= OnDialogClosed;
  58. dataContextConfiguration.OnCloseAction();
  59. return result;
  60. }
  61. private static void OnDialogClosed(object sender, DialogResultRoutedEventArgs e)
  62. {
  63. var dialog = sender as DialogContainer;
  64. var taskCompletionSource = dialog.Tag as TaskCompletionSource<object>;
  65. taskCompletionSource.TrySetResult(e.Result);
  66. dialog.DialogContent = null;
  67. dialog.AfterClose -= OnDialogClosed;
  68. dialog.Tag = null;
  69. }
  70. /// <summary>
  71. /// 显示指定对话框
  72. /// </summary>
  73. /// <param name="identifier">DialogContainer 标识</param>
  74. /// <param name="content">内容</param>
  75. /// <param name="parameters">参数</param>
  76. /// <param name="title">标题</param>
  77. /// <param name="openHandler">打开前处理程序</param>
  78. /// <param name="closeHandle">关闭后处理程序</param>
  79. /// <param name="showCloseButton">是否显示默认关闭按钮</param>
  80. /// <returns>结果</returns>
  81. public static async Task<object> Show(string identifier, object content, object parameters = null, string title = null, Action<DialogContainer> openHandler = null, Action<DialogContainer, object> closeHandle = null, bool? showCloseButton = null)
  82. {
  83. if (Dialogs.TryGetValue(identifier, out DialogContainer container))
  84. {
  85. return await ShowInternal(container, content, parameters, title, openHandler, closeHandle, showCloseButton);
  86. }
  87. throw new NullReferenceException($"The dialog container Identifier '{identifier}' could not be found");
  88. }
  89. /// <summary>
  90. /// 显示指定对话框
  91. /// (默认 BPA.UIControlWindow 下 DialogContainer 容器)
  92. /// </summary>
  93. /// <param name="content">内容</param>
  94. /// <param name="parameters">参数</param>
  95. /// <param name="title">标题</param>
  96. /// <param name="openHandler">打开前处理程序</param>
  97. /// <param name="closeHandle">关闭后处理程序</param>
  98. /// <param name="showCloseButton">是否显示默认关闭按钮</param>
  99. /// <returns>结果</returns>
  100. public static async Task<object> Show(object content, object parameters = null, string title = null, Action<DialogContainer> openHandler = null, Action<DialogContainer, object> closeHandle = null, bool? showCloseButton = null)
  101. {
  102. var activedWindow = WindowHelper.GetCurrentWindow() ?? throw new NullReferenceException("Can't find the actived window");
  103. DialogContainer container = activedWindow.TryGetChildFromVisualTree<DialogContainer>(null) ?? throw new NullReferenceException("Can't Find the DialogContainer");
  104. return await ShowInternal(container, content, parameters, title, openHandler, closeHandle, showCloseButton);
  105. }
  106. /// <summary>
  107. /// 关闭对话框
  108. /// </summary>
  109. /// <param name="identifier">标识</param>
  110. /// <param name="parameter">参数</param>
  111. public static void Close(string identifier, object parameter = null)
  112. {
  113. if (Dialogs.TryGetValue(identifier, out DialogContainer dialog))
  114. {
  115. DialogContainer.CloseDialogCommand.Execute(parameter, dialog);
  116. }
  117. }
  118. /// <summary>
  119. /// 关闭对话框
  120. /// </summary>
  121. /// <param name="dialog">对话框</param>
  122. /// <param name="parameter">参数</param>
  123. public static void Close(DialogContainer dialog, object parameter = null)
  124. {
  125. DialogContainer.CloseDialogCommand.Execute(parameter, dialog);
  126. }
  127. /// <summary>
  128. /// 关闭
  129. /// </summary>
  130. /// <param name="parameter">参数</param>
  131. /// <exception cref="NullReferenceException">找不到对话框</exception>
  132. public static void Close(object parameter = null)
  133. {
  134. var activedWindow = WindowHelper.GetCurrentWindow() ?? throw new NullReferenceException("Can't find the actived window");
  135. DialogContainer container = activedWindow.TryGetChildFromVisualTree<DialogContainer>(null) ?? throw new NullReferenceException("Can't Find the DialogContainer");
  136. Close(container, parameter);
  137. }
  138. }
  139. }