C# Winfom实现Toast功能

发布时间 2023-05-05 13:53:11作者: 寒風
    public class Toast
    {
        public class ToastInfo
        {
            public Form Owner { get; set; }
            public string Text { get; set; } = "";
            public bool Increase { get; set; } = true;
            public int StartTop { get; set; } = 20;
            public int Timeout { get; set; } = 2000;
            public Color BackColor { get; set; } = default;
            public Color TextColor { get; set; } = default;
        }
        [DllImport("Gdi32.dll", EntryPoint = "CreateRoundRectRgn")]
        public static extern IntPtr CreateRoundRectRgn
        (
            int nLeftRect, // x-coordinate of upper-left corner
            int nTopRect, // y-coordinate of upper-left corner
            int nRightRect, // x-coordinate of lower-right corner
            int nBottomRect, // y-coordinate of lower-right corner
            int nWidthEllipse, // width of ellipse
            int nHeightEllipse // height of ellipse
        );
        static object LockObject = new object();

        public static void Show(ToastInfo toastInfo)
        {
            if (toastInfo.Owner == null)
                return;

            var toasts = toastInfo.Owner.Controls.Cast<Control>().Where(v => v?.GetType() == typeof(ToastControl)).ToList();
            if (!toastInfo.Increase)
            {
                if (toasts.Count > 0)
                {
                    var firstToast = toasts[0] as ToastControl;
                    firstToast.timer1.Stop();
                    firstToast.ToastText = toastInfo.Text;
                    firstToast.timer1.Start();
                    return;
                }
            }
            var toast = new ToastControl();

            toast.Name = $"toast{toasts.Count}";
            toast.ToastText = toastInfo.Text;

            toast.Top =  (toasts.Count * (toast.Height + 5)) + toastInfo.StartTop;
            toast.Region = System.Drawing.Region.FromHrgn(CreateRoundRectRgn(0, 0, toast.Width, toast.Height, 5, 5));
            if (toastInfo.BackColor != default)
            {
                toast.BackColor = toastInfo.BackColor;
            }
            if (toastInfo.TextColor != default)
            {
                toast.lblMsg.ForeColor = toastInfo.TextColor;
            }
            toastInfo.Owner.Controls.Add(toast);

            toast.timer1.Interval = toastInfo.Timeout;
            toast.timer1.Tag = toast;
            toast.timer1.Tick += new EventHandler((s, e) =>
            {
                lock (LockObject)
                {
                    var timer = (s as Timer);
                    timer?.Stop();
                    var controlToast = timer.Tag as ToastControl;
                    toastInfo.Owner?.Controls.Remove(controlToast);
                    controlToast.Dispose();
                    var otherToasts = toastInfo.Owner.Controls.Cast<Control>().Where(v => v?.GetType() == typeof(ToastControl)).ToList();
                    for (int i = 0; i < otherToasts.Count; i++)
                    {
                        var toast2 = otherToasts[i];
                        toast2.Top -= (toast2.Height + 5);
                    }
                }
            });
            toast.timer1.Start();

            toast.Left = (int)(toastInfo.Owner.Width / 2 - toast.Width / 2);
            toast.Visible = true;
            toast.BringToFront();
        }


        public static void Info(string text, int timeOut = 2000, bool increase = true, int startTop = 20)
        {
            Show(new ToastInfo { Owner = Common.FindOwner(), Increase = increase, StartTop = startTop, Timeout = timeOut, Text = text, BackColor = ColorTranslator.FromHtml("#3C486B"), TextColor = Color.White });
        }
        public static void Error(string text = "發生錯誤!", int timeOut = 2000, bool increase = true, int startTop = 20)
        {
            Logs.Write(text);
            Show(new ToastInfo { Owner = Common.FindOwner(), Increase = increase, StartTop = startTop, Timeout = timeOut, Text = text, BackColor = ColorTranslator.FromHtml("#FF6D60"), TextColor = Color.White });
        }
        public static void Success(string text= "操作成功!", int timeOut = 2000, bool increase = true, int startTop = 20)
        {
            Show(new ToastInfo { Owner = Common.FindOwner(), Increase = increase, StartTop = startTop, Timeout = timeOut, Text = text, BackColor = ColorTranslator.FromHtml("#68B984"), TextColor = Color.White });
        }

    }

  使用方式:

  Toast.Error("一个错误的Toast!");