PopupHelper.cs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. using DevExpress.Utils;
  2. using DevExpress.Utils.Win;
  3. using DevExpress.XtraBars.Docking2010;
  4. using DevExpress.XtraEditors;
  5. using DevExpress.XtraEditors.ButtonsPanelControl;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Drawing;
  9. using System.Linq;
  10. using System.Text;
  11. using System.Threading.Tasks;
  12. using System.Windows.Forms;
  13. namespace DxHelper
  14. {
  15. /// <summary>
  16. /// Popup窗体弹出方向
  17. /// </summary>
  18. public enum EnumPopupDirection
  19. {
  20. /// <summary>
  21. /// 左侧弹出
  22. /// </summary>
  23. Left,
  24. /// <summary>
  25. /// 右侧弹出
  26. /// </summary>
  27. Right,
  28. /// <summary>
  29. /// 顶部弹出
  30. /// </summary>
  31. Top,
  32. /// <summary>
  33. /// 底部弹出
  34. /// </summary>
  35. Bottom,
  36. }
  37. /// <summary>
  38. /// Popup窗体弹出动画
  39. /// </summary>
  40. public enum EnumPopupAnimation
  41. {
  42. /// <summary>
  43. /// 无动画,立即显示或隐藏
  44. /// </summary>
  45. None,
  46. /// <summary>
  47. /// 颜色淡入淡出
  48. /// </summary>
  49. Fade,
  50. /// <summary>
  51. /// 抽屉滑入滑出
  52. /// </summary>
  53. Slide
  54. }
  55. /// <summary>
  56. /// Popup窗体关闭原因枚举
  57. /// </summary>
  58. public enum HideReason
  59. {
  60. /// <summary>
  61. /// 自动关闭或点击了默认的关闭按钮
  62. /// </summary>
  63. Defalut,
  64. /// <summary>
  65. /// 主动调用了PopupHelper.Hide方法
  66. /// </summary>
  67. CallHideMethod
  68. }
  69. public static class PopupHelper
  70. {
  71. private static Dictionary<Control, FlyoutPanel> dic = new Dictionary<Control, FlyoutPanel>();
  72. /// <summary>
  73. /// 从popup窗体中弹出content
  74. /// </summary>
  75. /// <param name="content">要显示的control,content必须是一个容器控件,如Panel、Form等</param>
  76. /// <param name="owner">popup窗体的父容器</param>
  77. /// <param name="size">popup窗体的大小,为0时将使用owner的大小</param>
  78. /// <param name="direct">窗体弹出位置</param>
  79. /// <param name="animation">弹出动画</param>
  80. /// <param name="showCloseButton">是否显示关闭按钮</param>
  81. /// <param name="autoClose">点击窗体外部是否自动关闭popup窗体</param>
  82. /// <param name="renderDone">渲染完成后的回调函数</param>
  83. public static void ShowPopup(Control content, Control owner, int size = 0, EnumPopupDirection direct = EnumPopupDirection.Right, EnumPopupAnimation animation = EnumPopupAnimation.Slide, bool showCloseButton = true, bool autoClose = false, Action onShown = null, Action<HideReason> onHide =null)
  84. {
  85. FlyoutPanel docker;
  86. if (!dic.ContainsKey(content))
  87. {
  88. docker = new FlyoutPanel();
  89. if (showCloseButton)
  90. {
  91. docker.OptionsButtonPanel.ShowButtonPanel = true;
  92. ButtonImageOptions options = new ButtonImageOptions();
  93. options.SvgImage = SvgHelper.CreateClose();
  94. options.SvgImageSize = new System.Drawing.Size(16, 16);
  95. var btnClose = new PeekFormButton("", true, options, ButtonStyle.PushButton, "", -1, true, null, true, false, true, null, -1, false);
  96. btnClose.Click += (sender, e) =>
  97. {
  98. docker?.HidePopup();
  99. };
  100. docker.OptionsButtonPanel.Buttons.Add(btnClose);
  101. docker.OptionsButtonPanel.ButtonPanelContentAlignment = ContentAlignment.MiddleLeft;
  102. docker.OptionsButtonPanel.ButtonPanelHeight = 24;
  103. }
  104. var panel = new FlyoutPanelControl(docker) { Dock = DockStyle.Fill };
  105. docker.Controls.Add(panel);
  106. dic.Add(content, docker);
  107. }
  108. else
  109. docker = dic[content];
  110. if (docker.IsPopupOpen)
  111. docker.HidePopup();
  112. else
  113. {
  114. if (owner != null)
  115. {
  116. docker.OwnerControl = owner;
  117. }
  118. if (docker.OwnerControl == null)
  119. {
  120. var parent = content.Parent;
  121. while (!(parent is Form))
  122. {
  123. parent = parent.Parent;
  124. }
  125. docker.OwnerControl = parent;
  126. }
  127. if (size > 0)
  128. docker.Width = docker.Height = size;
  129. else
  130. {
  131. docker.Width = owner.Width;
  132. docker.Height = owner.Height;
  133. owner.SizeChanged += (sender, e) =>
  134. {
  135. if (docker.Parent != null)
  136. docker.Parent.Size = new Size(owner.Width, owner.Height);
  137. };
  138. }
  139. docker.Options.CloseOnOuterClick = autoClose;
  140. if (animation == EnumPopupAnimation.Slide)
  141. docker.Options.AnimationType = PopupToolWindowAnimation.Slide;
  142. else
  143. docker.Options.AnimationType = PopupToolWindowAnimation.Fade;
  144. PopupToolWindowAnchor anchor = PopupToolWindowAnchor.Right;
  145. switch (direct)
  146. {
  147. case EnumPopupDirection.Left:
  148. anchor = PopupToolWindowAnchor.Left;
  149. break;
  150. case EnumPopupDirection.Right:
  151. anchor = PopupToolWindowAnchor.Right;
  152. break;
  153. case EnumPopupDirection.Top:
  154. anchor = PopupToolWindowAnchor.Top;
  155. break;
  156. case EnumPopupDirection.Bottom:
  157. anchor = PopupToolWindowAnchor.Bottom;
  158. break;
  159. }
  160. docker.Options.AnchorType = anchor;
  161. docker.Controls[0].Controls.Clear();
  162. content.Dock = DockStyle.Fill;
  163. if (content is Form)
  164. content.Controls[0].Parent = docker.Controls[0];
  165. else
  166. content.Parent = docker.Controls[0];
  167. bool immediate = animation == EnumPopupAnimation.None;
  168. docker.Shown += (sender, e) =>
  169. {
  170. onShown?.Invoke();
  171. };
  172. docker.Hidden += (sender, e) =>
  173. {
  174. if ((sender as Control).Tag != null)
  175. onHide?.Invoke(HideReason.CallHideMethod);
  176. else
  177. onHide?.Invoke(HideReason.Defalut);
  178. };
  179. docker.ShowPopup(immediate);
  180. }
  181. }
  182. public static void HidePopup(Control content)
  183. {
  184. if (content.Parent == null || content.Parent.Parent == null) return;
  185. var docker = content.Parent.Parent as FlyoutPanel;
  186. docker.Tag = "HidePopup";
  187. docker?.HidePopup();
  188. }
  189. }
  190. }