using DevExpress.Utils; using DevExpress.Utils.Win; using DevExpress.XtraBars.Docking2010; using DevExpress.XtraEditors; using DevExpress.XtraEditors.ButtonsPanelControl; using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace DxHelper { /// /// Popup窗体弹出方向 /// public enum EnumPopupDirection { /// /// 左侧弹出 /// Left, /// /// 右侧弹出 /// Right, /// /// 顶部弹出 /// Top, /// /// 底部弹出 /// Bottom, } /// /// Popup窗体弹出动画 /// public enum EnumPopupAnimation { /// /// 无动画,立即显示或隐藏 /// None, /// /// 颜色淡入淡出 /// Fade, /// /// 抽屉滑入滑出 /// Slide } public static class PopupHelper { private static Dictionary dic = new Dictionary(); /// /// 从popup窗体中弹出content /// /// 要显示的control,content必须是一个容器控件,如Panel、Form等 /// popup窗体的父容器 /// popup窗体的大小,为0时将使用owner的大小 /// 窗体弹出位置 /// 弹出动画 /// 是否显示关闭按钮 /// 点击窗体外部是否自动关闭popup窗体 /// 渲染完成后的回调函数 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 renderDone = null) { foreach (var item in dic.Values) { item.HidePopup(); } FlyoutPanel docker; if (!dic.ContainsKey(content)) { docker = new FlyoutPanel(); if (showCloseButton) { docker.OptionsButtonPanel.ShowButtonPanel = true; ButtonImageOptions options = new ButtonImageOptions(); options.SvgImage = SvgHelper.CreateClose(); options.SvgImageSize = new System.Drawing.Size(16, 16); var btnClose = new PeekFormButton("", true, options, ButtonStyle.PushButton, "", -1, true, null, true, false, true, null, -1, false); btnClose.Click += (sender, e) => { docker.Tag = "btnClose"; docker?.HidePopup(); }; docker.OptionsButtonPanel.Buttons.Add(btnClose); docker.OptionsButtonPanel.ButtonPanelContentAlignment = ContentAlignment.MiddleLeft; docker.OptionsButtonPanel.ButtonPanelHeight = 24; } var panel = new FlyoutPanelControl(docker) { Dock = DockStyle.Fill }; docker.Controls.Add(panel); dic.Add(content, docker); } else docker = dic[content]; if (docker.IsPopupOpen) docker.HidePopup(); else { if (owner != null) { docker.OwnerControl = owner; } if (docker.OwnerControl == null) { var parent = content.Parent; while (!(parent is Form)) { parent = parent.Parent; } docker.OwnerControl = parent; } if (size > 0) docker.Width = docker.Height = size; else { docker.Width = owner.Width; docker.Height = owner.Height; owner.SizeChanged += (sender, e) => { if (docker.Parent != null) docker.Parent.Size = new Size(owner.Width, owner.Height); }; } docker.Options.CloseOnOuterClick = autoClose; docker.Options.CloseOnHidingOwner = autoClose; if (animation == EnumPopupAnimation.Slide) docker.Options.AnimationType = PopupToolWindowAnimation.Slide; else docker.Options.AnimationType = PopupToolWindowAnimation.Fade; PopupToolWindowAnchor anchor = PopupToolWindowAnchor.Right; switch (direct) { case EnumPopupDirection.Left: anchor = PopupToolWindowAnchor.Left; break; case EnumPopupDirection.Right: anchor = PopupToolWindowAnchor.Right; break; case EnumPopupDirection.Top: anchor = PopupToolWindowAnchor.Top; break; case EnumPopupDirection.Bottom: anchor = PopupToolWindowAnchor.Bottom; break; } docker.Options.AnchorType = anchor; docker.Controls[0].Controls.Clear(); content.Dock = DockStyle.Fill; if (content is Form) content.Controls[0].Parent = docker.Controls[0]; else content.Parent = docker.Controls[0]; bool immediate = animation == EnumPopupAnimation.None; docker.ShowPopup(immediate); docker.Shown += (sender, e) => { renderDone?.Invoke(); }; } } public static void HidePopup(Control content) { if (content.Parent == null || content.Parent.Parent == null) return; var docker = content.Parent.Parent as FlyoutPanel; docker?.HidePopup(); } } }