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
}
}