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();
}
}
}