纯手画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。

效果如下:

三、代码以及思路

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)
{
Duration = duration * 1000;
Direction = direction;
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.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);

五、nuget下载使用

1.nuget包管理器控制台

Install-Package Alert_Form -Version 1.1.2.2

2.nuget包管理器GUI下载

注:

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

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

版权声明

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

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

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

纯手画WinForm的Alert提示弹出框的更多相关文章

  1. 四种常见的提示弹出框(success,warning,error,loading)原生JavaScript和jQuery分别实现

    原文:四种常见的提示弹出框(success,warning,error,loading)原生JavaScript和jQuery分别实现 虽然说现在官方的自带插件已经有很多了,但是有时候往往不能满足我们 ...

  2. Winform form窗体已弹出框的形式出现并回传值

    From2(弹出框)回传数据到From1 Form1(数据接收form): public string Sstr; private void button1_Click(object sender, ...

  3. 讨论asp.net通过机器cookie仿百度(google)实现搜索input搜索提示弹出框自己主动

    为实现自己主动弹出通过用户输入关键词相关的搜索结果,在这里,我举两个解决方案,对于两个不同的方案. 常用的方法是建立一个用户数据库中查找关系表.然后输入用户搜索框keyword异步调用数据表中的相关数 ...

  4. iOS自定义提示弹出框(类似UIAlertView)

    菜鸟一枚,大神勿喷.自己在牛刀小试的时候,发现系统的UIAlertView有点不喜欢,然后就自己自定义了一个UIAlertView,基本上实现了系统的UIAlertView,可以根据项目的需求修改UI ...

  5. iOS 提交代码出现提示弹出框显示 “A commit message is required to perform this operation.Enter a commit message and try again.“

    需要你写一下你确认提交的信息,就是你这次提交上去修改了什么功能,简单描述一下

  6. C# Winform 模拟QQ新闻弹出框

    一开始做的时候,觉得这个太简单了.真心做的时候还是遇到了不少的坑啊. 1)循环播放新闻内容,建议使用showdialog(),不要用show(),不太好控制前后之间的停顿. 2)窗口的初始位置为有下角 ...

  7. JS组件系列——Bootstrap寒冬暖身篇:弹出框和提示框效果以及代码展示

    前言:对于Web开发人员,弹出框和提示框的使用肯定不会陌生,比如常见的表格新增和编辑功能,一般常见的主要有两种处理方式:行内编辑和弹出框编辑.在增加用户体验方面,弹出框和提示框起着重要的作用,如果你的 ...

  8. Bootstrap:弹出框和提示框效果以及代码展示

    前言:对于Web开发人员,弹出框和提示框的使用肯定不会陌生,比如常见的表格新增和编辑功能,一般常见的主要有两种处理方式:行内编辑和弹出框编辑.在增加用户体验方面,弹出框和提示框起着重要的作用,如果你的 ...

  9. JS组件Bootstrap实现弹出框和提示框效果代码

    这篇文章主要介绍了JS组件Bootstrap实现弹出框和提示框效果代码,对弹出框和提示框感兴趣的小伙伴们可以参考一下 前言:对于Web开发人员,弹出框和提示框的使用肯定不会陌生,比如常见的表格新增和编 ...

随机推荐

  1. Java值引用和对象引用区别Demo

    转自:http://blog.csdn.net/gundsoul/article/details/4927404 以前就知道JAVA对象分对象引用和值引用,并且还知道8种基础数据类型,即引用时是值引用 ...

  2. Docker 安装&卸载

    不同版本可能有差异具体信息查看官网 官网:https://docs.docker.com/engine/install/centos/ #环境准备 #查看环境 uname -r # 系统内核在3.10 ...

  3. LuoguP7426 [THUPC2017] 体育成绩统计 题解

    Update \(\texttt{2021.3.11}\) 修复了一个笔误. Content 太长了,请直接跳转回题面查看. 数据范围:\(n\leqslant 10^4\),\(0\leqslant ...

  4. shell判断新字符串列表是否在老字符串列表中

    for sn in `cat 12.30-new`;do if ! [[ `cat 12.30-old` =~ $sn ]];then echo $sn; fi; done

  5. SpringBoot简单整合Gateway网关

    引入依赖 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>s ...

  6. RPA账户和密码管理方案

    如何将登录业务系统的账户和密码"更好的,更合适"地交给RPA? 相信很多小伙伴们在做RPA的时候, 都会或多或少的遇到类似的问题. 正常情况下IT管理人员都会给真实的业务人员分配业 ...

  7. c++11之all_of 、 any_of 和 none_of 的用法

    0.时刻提醒自己 Note: vector的释放 1.区别 函数 功能 all_of 区间[开始, 结束)中是否所有的元素都满足判断式p,所有的元素都满足条件返回true,否则返回false. any ...

  8. 再谈多线程模型之生产者消费者(多生产者和多消费者 )(c++11实现)

    0.关于 为缩短篇幅,本系列记录如下: 再谈多线程模型之生产者消费者(基础概念)(c++11实现) 再谈多线程模型之生产者消费者(单一生产者和单一消费者)(c++11实现) 再谈多线程模型之生产者消费 ...

  9. 【剑指Offer】数值的整数次方 解题报告(Python)

    [剑指Offer]数值的整数次方 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https://www.nowcoder.com/ta/coding-interviews ...

  10. 【LeetCode】427. Construct Quad Tree 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...