純手畫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)
{
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);
五、nuget下載使用
1.nuget包管理器控制檯
Install-Package Alert_Form -Version 1.1.2.2
2.nuget包管理器GUI下載
注:
1.這個包並不會長期維護,因為我只是為了學習nuget釋出包以及自己寫winform專案會用到而弄的。
2.自己封裝其實主要是為了學習和改變對winform醜的看法,實際上現在已經有很多winform的UI框架了,比如:SunnyUI、HZHControls、SyncfusionUI等。自己造沒有太大的必要。對於字型自適應,我這裡也做的不好,文字太多了字號就會小到看不清。主要還是以學習為主。
版權宣告
本文首發連結為:https://www.cnblogs.com/hyx1229/p/15801474.html
作者:不想只會CURD的猿某人
更多原著文章請參考:https://www.cnblogs.com/hyx1229/