using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Controls; using System.Windows; using System.Windows.Input; using BPA.UIControl.Commons; namespace BPA.UIControl { /// /// 通知操作类 /// public class Notification { /// /// Transition 动画时长 /// public const int TransitionTime = 300; /// /// 所有容器集合 /// internal static Dictionary Containers = new Dictionary(); /// /// 更新容器 /// /// 容器 /// 标识 internal static void UpdateContainer(NotificationContainer container, string identify) { if (Containers.ContainsKey(identify)) { _ = Containers.Remove(identify); } Containers.Add(identify, container); } private static NotificationCard GetNotificationCard(NotificationType type, object content, string title, int millisecondTimeOut, bool isClearable) { var notificationCard = new NotificationCard { Type = type, Content = content, IsClearable = isClearable, }; if (!string.IsNullOrEmpty(title)) { notificationCard.Title = title; } return notificationCard; } /// /// 延期关闭通知卡片 /// /// 显示时间,为 0 时不自动关闭 /// 通知卡片 /// 取消令牌 private static void DelayCloseNotificationCard(int millisecondTimeOut, NotificationCard notificationCard, CancellationToken token) { if (millisecondTimeOut > 0) { _ = Task.Run(async () => { await Task.Delay(millisecondTimeOut + TransitionTime, token); Application.Current.Dispatcher.Invoke(() => { notificationCard.IsShow = false; }); }, token); } } #region 全局 /// /// 全局显示 /// /// 类型 /// 内容 /// 标题 /// 关闭延时,为 0 时不自动关闭 /// 是否显示关闭按钮 public static void ShowGlobal(NotificationType type, object content, string title = "", int millisecondTimeOut = 3000, bool isClearable = true) { NotificationWindow notificationWindow = NotificationWindow.GetInstance(); notificationWindow.Dispatcher.VerifyAccess(); NotificationCard notificationCard = GetNotificationCard(type, content, title, millisecondTimeOut, isClearable); CancellationTokenSource cts = new CancellationTokenSource(); notificationCard.Close += (sender, e) => notificationWindow.RemoveMessageCard(notificationCard); notificationCard.MouseEnter += (sender, e) => cts.Cancel(); notificationCard.MouseLeave += (sender, e) => { cts = new CancellationTokenSource(); DelayCloseNotificationCard(millisecondTimeOut, notificationCard, cts.Token); }; notificationWindow.Show(); notificationWindow.AddMessageCard(notificationCard); DelayCloseNotificationCard(millisecondTimeOut, notificationCard, cts.Token); } /// /// 全局显示 /// /// 内容 /// 标题 /// 关闭延时,为 0 时不自动关闭 /// 是否显示关闭按钮 public static void ShowGlobal(object content, string title = "", int millisecondTimeOut = 3000, bool isClearable = true) { ShowGlobal(NotificationType.None, content, title, millisecondTimeOut, isClearable); } /// /// 全局显示信息 /// /// 内容 /// 标题 /// 关闭延时,为 0 时不自动关闭 /// 是否显示关闭按钮 public static void InfoGlobal(object content, string title = "", int millisecondTimeOut = 3000, bool isClearable = true) { ShowGlobal(NotificationType.Info, content, title, millisecondTimeOut, isClearable); } /// /// 全局显示成功 /// /// 内容 /// 标题 /// 关闭延时,为 0 时不自动关闭 /// 是否显示关闭按钮 public static void SuccessGlobal(object content, string title = "", int millisecondTimeOut = 3000, bool isClearable = true) { ShowGlobal(NotificationType.Success, content, title, millisecondTimeOut, isClearable); } /// /// 全局显示警告 /// /// 内容 /// 标题 /// 关闭延时,为 0 时不自动关闭 /// 是否显示关闭按钮 public static void WarningGlobal(object content, string title = "", int millisecondTimeOut = 3000, bool isClearable = true) { ShowGlobal(NotificationType.Warning, content, title, millisecondTimeOut, isClearable); } /// /// 全局显示错误 /// /// 内容 /// 标题 /// 关闭延时,为 0 时不自动关闭 /// 是否显示关闭按钮 public static void ErrorGlobal(object content, string title = "", int millisecondTimeOut = 3000, bool isClearable = true) { ShowGlobal(NotificationType.Error, content, title, millisecondTimeOut, isClearable); } #endregion 全局 #region 指定容器 private static void ShowInternal(NotificationContainer container, NotificationType type, object content, string title, int millisecondTimeOut, bool isClearable) { container.Dispatcher.VerifyAccess(); NotificationCard notificationCard = GetNotificationCard(type, content, title, millisecondTimeOut, isClearable); CancellationTokenSource cts = new CancellationTokenSource(); notificationCard.Close += (sender, e) => container.RemoveCard(notificationCard); notificationCard.MouseEnter += (sender, e) => cts.Cancel(); notificationCard.MouseLeave += (sender, e) => { cts = new CancellationTokenSource(); DelayCloseNotificationCard(millisecondTimeOut, notificationCard, cts.Token); }; container.AddCard(notificationCard); DelayCloseNotificationCard(millisecondTimeOut, notificationCard, cts.Token); } /// /// 容器内显示 /// /// 容器 ID /// 类型 /// 标题 /// 内容 /// 关闭延时,为 0 时不自动关闭 /// 是否显示关闭按钮 public static void Show(string containerIdentifier, NotificationType type, object content, string title = "", int millisecondTimeOut = 5000, bool isClearable = true) { if (!Containers.ContainsKey(containerIdentifier)) { throw new NullReferenceException($"The notification container Identifier '{containerIdentifier}' could not be found"); } NotificationContainer container = Containers[containerIdentifier]; ShowInternal(container, type, content, title, millisecondTimeOut, isClearable); } /// /// 容器内显示 /// (默认 Actived Window 下顶层 MessageContainer 容器) /// /// 类型 /// 内容 /// 标题 /// 关闭延时,为 0 时不自动关闭 /// 是否显示关闭按钮 public static void Show(NotificationType type, object content, string title = "", int millisecondTimeOut = 3000, bool isClearable = true) { var activedWindow = WindowHelper.GetCurrentWindow() ?? throw new NullReferenceException("Can't find the actived window"); NotificationContainer container = activedWindow.TryGetChildFromVisualTree(null) ?? throw new NullReferenceException("Can't Find the NotificationContainer"); ShowInternal(container, type, content, title, millisecondTimeOut, isClearable); } /// /// 容器内显示 /// /// 容器 ID /// 内容 /// 标题 /// 关闭延时,为 0 时不自动关闭 /// 是否显示关闭按钮 public static void Show(string containerIdentifier, object content, string title = "", int millisecondTimeOut = 3000, bool isClearable = true) { Show(containerIdentifier, NotificationType.None, content, title, millisecondTimeOut, isClearable); } /// /// 容器内显示 /// /// 内容 /// 标题 /// 关闭延时,为 0 时不自动关闭 /// 是否显示关闭按钮 public static void Show(object content, string title = "", int millisecondTimeOut = 3000, bool isClearable = true) { Show(NotificationType.None, content, title, millisecondTimeOut, isClearable); } /// /// 容器内显示信息 /// /// 容器 ID /// 内容 /// 标题 /// 关闭延时,为 0 时不自动关闭 /// 是否显示关闭按钮 public static void Info(string containerIdentifier, object content, string title = "", int millisecondTimeOut = 3000, bool isClearable = true) { Show(containerIdentifier, NotificationType.Info, content, title, millisecondTimeOut, isClearable); } /// /// 容器内显示信息 /// (默认 Actived Window 下顶层 MessageContainer 容器) /// /// 内容 /// 标题 /// 关闭延时,为 0 时不自动关闭 /// 是否显示关闭按钮 public static void Info(object content, string title = "", int millisecondTimeOut = 3000, bool isClearable = true) { Show(NotificationType.Info, content, title, millisecondTimeOut, isClearable); } /// /// 容器内显示成功 /// /// 容器 ID /// 内容 /// 标题 /// 关闭延时,为 0 时不自动关闭 /// 是否显示关闭按钮 public static void Success(string containerIdentifier, object content, string title = "", int millisecondTimeOut = 3000, bool isClearable = true) { Show(containerIdentifier, NotificationType.Success, content, title, millisecondTimeOut, isClearable); } /// /// 容器内显示成功 /// (默认 Actived Window 下顶层 MessageContainer 容器) /// /// 内容 /// 标题 /// 关闭延时,为 0 时不自动关闭 /// 是否显示关闭按钮 public static void Success(object content, string title = "", int millisecondTimeOut = 3000, bool isClearable = true) { Show(NotificationType.Success, content, title, millisecondTimeOut, isClearable); } /// /// 容器内显示警告 /// /// 容器 ID /// 内容 /// 标题 /// 关闭延时,为 0 时不自动关闭 /// 是否显示关闭按钮 public static void Warning(string containerIdentifier, object content, string title = "", int millisecondTimeOut = 3000, bool isClearable = true) { Show(containerIdentifier, NotificationType.Warning, content, title, millisecondTimeOut, isClearable); } /// /// 容器内显示警告 /// (默认 Actived Window 下顶层 MessageContainer 容器) /// /// 内容 /// 标题 /// 关闭延时,为 0 时不自动关闭 /// 是否显示关闭按钮 public static void Warning(object content, string title = "", int millisecondTimeOut = 3000, bool isClearable = true) { Show(NotificationType.Warning, content, title, millisecondTimeOut, isClearable); } /// /// 容器内显示错误 /// /// 容器 ID /// 内容 /// 标题 /// 关闭延时,为 0 时不自动关闭 /// 是否显示关闭按钮 public static void Error(string containerIdentifier, object content, string title = "", int millisecondTimeOut = 3000, bool isClearable = true) { Show(containerIdentifier, NotificationType.Error, content, title, millisecondTimeOut, isClearable); } /// /// 容器内显示错误 /// (默认 Actived Window 下顶层 MessageContainer 容器) /// /// 内容 /// 标题 /// 关闭延时,为 0 时不自动关闭 /// 是否显示关闭按钮 public static void Error(object content, string title = "", int millisecondTimeOut = 3000, bool isClearable = true) { Show(NotificationType.Error, content, title, millisecondTimeOut, isClearable); } #endregion 指定容器 } /// /// 通知类型 /// public enum NotificationType { /// /// 无 /// [Description("无")] None = 0, /// /// 信息 /// [Description("信息")] Info, /// /// 成功 /// [Description("成功")] Success, /// /// 警告 /// [Description("警告")] Warning, /// /// 错误 /// [Description("错误")] Error } }