• 纯手撸WinForm的Alert提示弹出框


    纯手撸WinForm的Alert弹框

    一、窗体设置

    设置以下属性:

    属性名 属性值 说明
    AutoScaleMode None 确定屏幕分辨率或字体更改时窗体如何缩放
    BackColor 103, 194, 58 背景色
    Font Microsoft Sans Serif, 14.25pt 字体
    FormBorderStyle None 标题栏和边框样式
    ShowIcon False 是否显示窗体图标
    ShowInTaskBar False 是否显示在Windows任务栏
    Size 450,100 窗体大小
    TopMost True 窗口置顶

    二、界面控件

    两个PictureBox和一个Label以及一个定时器,控件大小大家自己定义吧,PictureBox设置SizeMode的值为Zoom,Label的ForeColor为white,AutoSIze为True。

    效果如下:

    image

    三、代码以及思路

    1.首先新建三个枚举类:AlertTypes.cs、ActionType.cs、ShowDirection.cs

    AlertTypes控制弹框的类型,ActionType弹框的状态,ShowDirection弹框的显示位置

    public enum AlertType
    {
        /// <summary>
        /// 成功
        /// </summary>
        Success,
        /// <summary>
        /// 提示
        /// </summary>
        Info,
        /// <summary>
        /// 错误
        /// </summary>
        Error,
        /// <summary>
        /// 警告
        /// </summary>
        Warning
    }
    public enum ActionType
    {
        /// <summary>
        /// 等待
        /// </summary>
        wait,
        /// <summary>
        /// 开启
        /// </summary>
        start,
        /// <summary>
        /// 关闭
        /// </summary>
        close
    }
    public enum ShowDirection
    {
        /// <summary>
        /// 头部中心
        /// </summary>
        TopCenter,
        /// <summary>
        /// 右下角
        /// </summary>
        BottomRight,
        /// <summary>
        /// 右上角
        /// </summary>
        TopRight,
    }
    

    2.思路

    1.滑动的效果通过可以通过定时器修改位置

    2.隐藏的效果可以通过控制透明度

    3.每一种类型的Alert最多只能弹出10个

    3.代码实现

    1.公共变量

    /// <summary>
    /// Alert类型
    /// </summary>
    private ActionType action;
    /// <summary>
    /// 位置Point
    /// </summary>
    private int x, y;
    /// <summary>
    /// 动画持续的时间
    /// </summary>
    private int Duration;
    /// <summary>
    /// 弹出的位置
    /// </summary>
    private ShowDirection Direction;
    

    2.showAlert方法

    • 定义窗体的初始位置以及窗体最后的位置并调用this.Show()
    • 设置行为状态为ActionType.start
    • 启动定时器
    /// <summary>
    /// 内部调用显示窗体
    /// </summary>
    /// <param name="msg"></param>
    protected void ShowAlert(string msg)
    {
        this.Opacity = 0.0;
        this.StartPosition = FormStartPosition.Manual;
    
        string fname;
    
        for (int i = 1; i < 10; i++)
        {
            fname = "alert" + i.ToString() + Direction.ToString();
            AlertForm frm = (AlertForm)Application.OpenForms[fname];
            if (frm == null)
            {
                this.Name = fname;
                // 初始位置
                switch (Direction)
                {
                    case ShowDirection.TopCenter:
                        this.x = (Screen.PrimaryScreen.WorkingArea.Width - this.Width) / 2;
                        this.y = this.Height * i + 5 * i;
                        break;
                    case ShowDirection.BottomRight:
                        this.x = Screen.PrimaryScreen.WorkingArea.Width - this.Width + 15;
                        this.y = Screen.PrimaryScreen.WorkingArea.Height - this.Height * i - 5 * i;
                        break;
                    case ShowDirection.TopRight:
                        this.x = Screen.PrimaryScreen.WorkingArea.Width - this.Width + 15;
                        this.y = this.Height * i + 5 * i;
                        break;
                }
                this.Location = new Point(this.x, this.y);
                break;
            }
        }
    
        // 横向最后的显示位置 形成滑动距离
        switch (Direction)
        {
            case ShowDirection.BottomRight:
            case ShowDirection.TopRight:
                this.x = Screen.PrimaryScreen.WorkingArea.Width - base.Width - 5;
                break;
        }
    
        this.lbMsg.Text = msg;
        //字体大小自适应
        LabelAutoSize();
        this.Show();
        this.action = ActionType.start;
        this.hideTimer.Interval = 1;
        this.hideTimer.Start();
    }
    

    3.定时器事件控制动画效果

    private void hideTimer_Tick(object sender, EventArgs e)
    {
        switch (this.action)
        {
            case ActionType.wait:
                this.hideTimer.Interval = Duration;
                this.action = ActionType.close;
                break;
            case ActionType.start:
                this.hideTimer.Interval = 1;
                this.Opacity += 0.1;
                switch (Direction)
                {
                    case ShowDirection.TopCenter:
                        if (this.Opacity.Equals(1.0))
                        {
                            this.action = ActionType.wait;
                        }
                        break;
                    case ShowDirection.BottomRight:
                    case ShowDirection.TopRight:
                        if (this.x < this.Location.X)
                        {
                            this.Left--;
                        }
                        else
                        {
                            if (this.Opacity.Equals(1.0))
                            {
                                this.action = ActionType.wait;
                            }
                        }
                        break;
                }
                break;
            case ActionType.close:
                this.hideTimer.Interval = 1;
                this.Opacity -= 0.1;
                if (Direction == ShowDirection.TopCenter)
                    this.Top -= 10;
                else
                    this.Left -= 3;
    
                if (base.Opacity == 0.0)
                    base.Close();
                break;
        }
    }
    

    4.暴露给外部使用的ShowAlert方法

    /// <summary>
    /// 暴露的方法
    /// </summary>
    /// <param name="msg">内容</param>
    /// <param name="type">弹出类型</param>
    /// <param name="duration">展示时间 秒</param>
    /// <param name="direction">位置</param>
    public static void ShowAlert(string msg, AlertType type,
                                 int duration = 3, ShowDirection direction = ShowDirection.TopCenter)
    {
        AlertForm alert = new AlertForm();
        switch (type)
        {
            case AlertType.Success:
                alert.picAlertType.Image = Resources.Success;
                alert.BackColor = Color.FromArgb(103, 194, 58);
                break;
            case AlertType.Info:
                alert.picAlertType.Image = Resources.Info;
                alert.BackColor = Color.FromArgb(64, 158, 255);
                break;
            case AlertType.Error:
                alert.picAlertType.Image = Resources.Error;
                alert.BackColor = Color.FromArgb(245, 108, 108);
                break;
            case AlertType.Warning:
                alert.picAlertType.Image = Resources.Warning;
                alert.BackColor = Color.FromArgb(230, 162, 60);
                break;
        }
        alert.Duration = duration * 1000;
        alert.Direction = direction;
        alert.ShowAlert(msg);
    
    }
    

    5.关闭按钮的事件

    private void btnPicClose_Click(object sender, EventArgs e)
    {
        this.hideTimer.Interval = 1;
        this.action = ActionType.close;
    }
    

    4.全部代码

    using Alert_Form.Properties;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Runtime.CompilerServices;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace Alert_Form.Component.Alert
    {
        public partial class AlertForm : Form
        {
            /// <summary>
            /// Alert类型
            /// </summary>
            private ActionType action;
            private int x, y;
            /// <summary>
            /// 动画持续的时间
            /// </summary>
            private int Duration;
            /// <summary>
            /// 弹出的位置
            /// </summary>
            private ShowDirection Direction;
            /// <summary>
            /// 暴露的方法
            /// </summary>
            /// <param name="msg">内容</param>
            /// <param name="type">弹出类型</param>
            /// <param name="duration">展示时间 秒</param>
            /// <param name="direction">位置</param>
            public static void ShowAlert(string msg, AlertType type,
                int duration = 3, ShowDirection direction = ShowDirection.TopCenter)
            {
                AlertForm alert = new AlertForm();
                switch (type)
                {
                    case AlertType.Success:
                        alert.picAlertType.Image = Resources.Success;
                        alert.BackColor = Color.FromArgb(103, 194, 58);
                        break;
                    case AlertType.Info:
                        alert.picAlertType.Image = Resources.Info;
                        alert.BackColor = Color.FromArgb(64, 158, 255);
                        break;
                    case AlertType.Error:
                        alert.picAlertType.Image = Resources.Error;
                        alert.BackColor = Color.FromArgb(245, 108, 108);
                        break;
                    case AlertType.Warning:
                        alert.picAlertType.Image = Resources.Warning;
                        alert.BackColor = Color.FromArgb(230, 162, 60);
                        break;
                }
                alert.Duration = duration * 1000;
                alert.Direction = direction;
                alert.ShowAlert(msg);
    
            }
            
            public AlertForm()
            {
                InitializeComponent();
            }
    
            private void btnPicClose_Click(object sender, EventArgs e)
            {
                this.hideTimer.Interval = 1;
                this.action = ActionType.close;
            }
    
            private void hideTimer_Tick(object sender, EventArgs e)
            {
                switch (this.action)
                {
                    case ActionType.wait:
                        this.hideTimer.Interval = Duration;
                        this.action = ActionType.close;
                        break;
                    case ActionType.start:
                        this.hideTimer.Interval = 1;
                        this.Opacity += 0.1;
                        switch (Direction)
                        {
                            case ShowDirection.TopCenter:
                                if (this.Opacity.Equals(1.0))
                                {
                                    this.action = ActionType.wait;
                                }
                                break;
                            case ShowDirection.BottomRight:
                            case ShowDirection.TopRight:
                                if (this.x < this.Location.X)
                                {
                                    this.Left--;
                                }
                                else
                                {
                                    if (this.Opacity.Equals(1.0))
                                    {
                                        this.action = ActionType.wait;
                                    }
                                }
                                break;
                        }
                        break;
                    case ActionType.close:
                        this.hideTimer.Interval = 1;
                        this.Opacity -= 0.1;
                        if (Direction == ShowDirection.TopCenter)
                            this.Top -= 10;
                        else
                            this.Left -= 3;
    
                        if (base.Opacity == 0.0)
                            base.Close();
                        break;
                }
            }
            /// <summary>
            /// 内部调用显示窗体
            /// </summary>
            /// <param name="msg"></param>
            protected void ShowAlert(string msg)
            {
                this.Opacity = 0.0;
                this.StartPosition = FormStartPosition.Manual;
    
                string fname;
    
                for (int i = 1; i < 10; i++)
                {
                    fname = "alert" + i.ToString() + Direction.ToString();
                    AlertForm frm = (AlertForm)Application.OpenForms[fname];
                    if (frm == null)
                    {
                        this.Name = fname;
                        // 初始位置
                        switch (Direction)
                        {
                            case ShowDirection.TopCenter:
                                this.x = (Screen.PrimaryScreen.WorkingArea.Width - this.Width) / 2;
                                this.y = this.Height * i + 5 * i;
                                break;
                            case ShowDirection.BottomRight:
                                this.x = Screen.PrimaryScreen.WorkingArea.Width - this.Width + 15;
                                this.y = Screen.PrimaryScreen.WorkingArea.Height - this.Height * i - 5 * i;
                                break;
                            case ShowDirection.TopRight:
                                this.x = Screen.PrimaryScreen.WorkingArea.Width - this.Width + 15;
                                this.y = this.Height * i + 5 * i;
                                break;
                        }
                        this.Location = new Point(this.x, this.y);
                        break;
                    }
                }
    
                // 横向最后的显示位置 形成滑动距离
                switch (Direction)
                {
                    case ShowDirection.BottomRight:
                    case ShowDirection.TopRight:
                        this.x = Screen.PrimaryScreen.WorkingArea.Width - base.Width - 5;
                        break;
                }
    
                this.lbMsg.Text = msg;
                //字体大小自适应
                LabelAutoSize();
                this.Show();
                this.action = ActionType.start;
                this.hideTimer.Interval = 1;
                this.hideTimer.Start();
            }
            /// <summary>
            /// msg文字大小自适应
            /// </summary>
            private void LabelAutoSize()
            {            
                Font font;
                while (true)
                {
                    var lbFont = this.lbMsg.Font;
                    if (lbMsg.Right >= this.btnPicClose.Left)
                    {
                        font = new Font(lbFont.Name,lbFont.Size-1,lbFont.Style);
                        this.lbMsg.Font = font;
                    }
                    else
                    {
                        var top = (this.Height - this.lbMsg.Height) / 2;
                        lbMsg.Top = top;
                        break;
                    }
                }            
            }
        }
    }
    
    

    四、最终效果

    调用:

    AlertForm.ShowAlert("Success MessageText",AlertType.Success,direction:ShowDirection.BottomRight);
    AlertForm.ShowAlert("Info MessageText", AlertType.Info,direction:ShowDirection.TopRight);
    AlertForm.ShowAlert("Error MessageText", AlertType.Error);
    AlertForm.ShowAlert("Warning MessageText",AlertType.Warning);
    

    image

    五、nuget下载使用

    1.nuget包管理器控制台

    Install-Package Alert_Form -Version 1.1.2.2

    2.nuget包管理器GUI下载

    image

    注:

    1.这个包并不会长期维护,因为我只是为了学习nuget发布包以及自己写winform项目会用到而弄的。

    2.自己封装其实主要是为了学习和改变对winform丑的看法,实际上现在已经有很多winform的UI框架了,比如:SunnyUIHZHControlsSyncfusionUI等。自己造没有太大的必要。对于字体自适应,我这里也做的不好,文字太多了字号就会小到看不清。主要还是以学习为主。

    版权声明

    本文首发链接为:https://www.cnblogs.com/hyx1229/p/15801474.html

    作者:不想只会CURD的猿某人

    更多原著文章请参考:https://www.cnblogs.com/hyx1229/

  • 相关阅读:
    数据库出现中文乱码解决方法
    OO第四次博客作业
    OO第三次博客作业
    OO第二次博客作业
    OO前三次作业反思
    mybatis怎么自动生成实体类,Mapper配置文件和Dao接口
    Win7+VS2013初试Thrift
    静态链接库与动态链接库
    排序算法总结
    TCP/IP协议详解
  • 原文地址:https://www.cnblogs.com/hyx1229/p/15801474.html
Copyright © 2020-2023  润新知