前提 入行已經7,8年了,一直想做一套漂亮點的自定義控制項,於是就有了本系列文章。 開源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control 如果覺得寫的還行,請點個 star 支持一下吧 歡迎前來交流探討: 企鵝群568015492 目錄 ...
前提
入行已經7,8年了,一直想做一套漂亮點的自定義控制項,於是就有了本系列文章。
開源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control
如果覺得寫的還行,請點個 star 支持一下吧
目錄
https://www.cnblogs.com/bfyx/p/11364884.html
準備工作
這個窗體繼承子基類窗體FrmBase,如果你對FrmBase還不瞭解,請移步 (十七)c#Winform自定義控制項-基類窗體 查看
氣泡需要支持多個位置顯示,也就是說四面八方都可以顯示,並且支持樣式,自定義大小,另外具有內置的4中模式(成功,錯誤,警告,正常)
開始
定義一些枚舉
1 public enum TipsSizeMode 2 { 3 Small, 4 Medium, 5 Large, 6 None 7 } 8 public enum TipsState 9 { 10 Default = -1, 11 Success = -6566849, 12 Info = -12477983, 13 Warning = -357816, 14 Error = -1097849 15 }
添加Form,命名FrmTips,繼承自FrmBase
屬性
1 private ContentAlignment m_showAlign = ContentAlignment.BottomLeft; 2 3 /// <summary> 4 /// 顯示位置 5 /// </summary> 6 public ContentAlignment ShowAlign 7 { 8 get { return m_showAlign; } 9 set { m_showAlign = value; } 10 } 11 12 private static List<FrmTips> m_lstTips = new List<FrmTips>(); 13 14 private int m_CloseTime = 0; 15 16 public int CloseTime 17 { 18 get { return m_CloseTime; } 19 set 20 { 21 m_CloseTime = value; 22 if (value > 0) 23 timer1.Interval = value; 24 } 25 }
提供一些公共函數
1 #region 清理提示框 2 /// <summary> 3 /// 功能描述:清理提示框 4 /// 作 者:HZH 5 /// 創建日期:2019-02-28 15:11:03 6 /// 任務編號:POS 7 /// </summary> 8 public static void ClearTips() 9 { 10 for (int i = m_lstTips.Count - 1; i >= 0; i--) 11 { 12 FrmTips current = m_lstTips[i]; 13 if (!current.IsDisposed) 14 { 15 current.Close(); 16 current.Dispose(); 17 } 18 } 19 m_lstTips.Clear(); 20 } 21 #endregion 22 23 /// <summary> 24 /// 重置倒計時 25 /// </summary> 26 public void ResetTimer() 27 { 28 if (m_CloseTime > 0) 29 { 30 timer1.Enabled = false; 31 timer1.Enabled = true; 32 } 33 }
提供的靜態函數
1 #region 清理提示框 2 /// <summary> 3 /// 功能描述:清理提示框 4 /// 作 者:HZH 5 /// 創建日期:2019-02-28 15:11:03 6 /// 任務編號:POS 7 /// </summary> 8 public static void ClearTips() 9 { 10 for (int i = m_lstTips.Count - 1; i >= 0; i--) 11 { 12 FrmTips current = m_lstTips[i]; 13 if (!current.IsDisposed) 14 { 15 current.Close(); 16 current.Dispose(); 17 } 18 } 19 m_lstTips.Clear(); 20 } 21 #endregion 22 23 24 private static KeyValuePair<string, FrmTips> m_lastTips = new KeyValuePair<string, FrmTips>(); 25 26 public static FrmTips ShowTips( 27 Form frm, 28 string strMsg, 29 int intAutoColseTime = 0, 30 bool blnShowCoseBtn = true, 31 ContentAlignment align = ContentAlignment.BottomLeft, 32 Point? point = null, 33 TipsSizeMode mode = TipsSizeMode.Small, 34 Size? size = null, 35 TipsState state = TipsState.Default) 36 { 37 38 if (m_lastTips.Key == strMsg + state && !m_lastTips.Value.IsDisposed && m_lastTips.Value.Visible) 39 { 40 m_lastTips.Value.ResetTimer(); 41 return m_lastTips.Value; 42 } 43 else 44 { 45 FrmTips frmTips = new FrmTips(); 46 switch (mode) 47 { 48 case TipsSizeMode.Small: 49 frmTips.Size = new Size(350, 35); 50 break; 51 case TipsSizeMode.Medium: 52 frmTips.Size = new Size(350, 50); 53 break; 54 case TipsSizeMode.Large: 55 frmTips.Size = new Size(350, 65); 56 break; 57 case TipsSizeMode.None: 58 if (!size.HasValue) 59 { 60 frmTips.Size = new Size(350, 35); 61 } 62 else 63 { 64 frmTips.Size = size.Value; 65 } 66 break; 67 } 68 frmTips.BackColor = Color.FromArgb((int)state); 69 70 if (state == TipsState.Default) 71 { 72 frmTips.lblMsg.ForeColor = SystemColors.ControlText; 73 } 74 else 75 { 76 frmTips.lblMsg.ForeColor = Color.White; 77 } 78 switch (state) 79 { 80 case TipsState.Default: 81 frmTips.pctStat.Image = HZH_Controls.Properties.Resources.alarm; 82 break; 83 case TipsState.Success: 84 frmTips.pctStat.Image = HZH_Controls.Properties.Resources.success; 85 break; 86 case TipsState.Info: 87 frmTips.pctStat.Image = HZH_Controls.Properties.Resources.alarm; 88 break; 89 case TipsState.Warning: 90 frmTips.pctStat.Image = HZH_Controls.Properties.Resources.warning; 91 break; 92 case TipsState.Error: 93 frmTips.pctStat.Image = HZH_Controls.Properties.Resources.error; 94 break; 95 default: 96 frmTips.pctStat.Image = HZH_Controls.Properties.Resources.alarm; 97 break; 98 } 99 100 frmTips.lblMsg.Text = strMsg; 101 frmTips.CloseTime = intAutoColseTime; 102 frmTips.btnClose.Visible = blnShowCoseBtn; 103 104 105 frmTips.ShowAlign = align; 106 frmTips.Owner = frm; 107 FrmTips.m_lstTips.Add(frmTips); 108 FrmTips.ReshowTips(); 109 frmTips.Show(frm); 110 if (frm != null && !frm.IsDisposed) 111 { 112 ControlHelper.SetForegroundWindow(frm.Handle); 113 } 114 //frmTips.BringToFront(); 115 m_lastTips = new KeyValuePair<string, FrmTips>(strMsg + state, frmTips); 116 return frmTips; 117 } 118 } 119 120 #region 刷新顯示 121 /// <summary> 122 /// 功能描述:刷新顯示 123 /// 作 者:HZH 124 /// 創建日期:2019-02-28 15:33:06 125 /// 任務編號:POS 126 /// </summary> 127 public static void ReshowTips() 128 { 129 lock (FrmTips.m_lstTips) 130 { 131 FrmTips.m_lstTips.RemoveAll(p => p.IsDisposed == true); 132 var enumerable = from p in FrmTips.m_lstTips 133 group p by new 134 { 135 p.ShowAlign 136 }; 137 Size size = Screen.PrimaryScreen.Bounds.Size; 138 foreach (var item in enumerable) 139 { 140 List<FrmTips> list = FrmTips.m_lstTips.FindAll((FrmTips p) => p.ShowAlign == item.Key.ShowAlign); 141 for (int i = 0; i < list.Count; i++) 142 { 143 FrmTips frmTips = list[i]; 144 if (frmTips.InvokeRequired) 145 { 146 frmTips.BeginInvoke(new MethodInvoker(delegate() 147 { 148 switch (item.Key.ShowAlign) 149 { 150 case ContentAlignment.BottomCenter: 151 frmTips.Location = new Point((size.Width - frmTips.Width) / 2, size.Height - 100 - (i + 1) * (frmTips.Height + 10)); 152 break; 153 case ContentAlignment.BottomLeft: 154 frmTips.Location = new Point(10, size.Height - 100 - (i + 1) * (frmTips.Height + 10)); 155 break; 156 case ContentAlignment.BottomRight: 157 frmTips.Location = new Point(size.Width - frmTips.Width - 10, size.Height - 100 - (i + 1) * (frmTips.Height + 10)); 158 break; 159 case ContentAlignment.MiddleCenter: 160 frmTips.Location = new Point((size.Width - frmTips.Width) / 2, size.Height - (size.Height - list.Count * (frmTips.Height + 10)) / 2 - (i + 1) * (frmTips.Height + 10)); 161 break; 162 case ContentAlignment.MiddleLeft: 163 frmTips.Location = new Point(10, size.Height - (size.Height - list.Count * (frmTips.Height + 10)) / 2 - (i + 1) * (frmTips.Height + 10)); 164 break; 165 case ContentAlignment.MiddleRight: 166 frmTips.Location = new Point(size.Width - frmTips.Width - 10, size.Height - (size.Height - list.Count * (frmTips.Height + 10)) / 2 - (i + 1) * (frmTips.Height + 10)); 167 break; 168 case ContentAlignment.TopCenter: 169 frmTips.Location = new Point((size.Width - frmTips.Width) / 2, 10 + (i + 1) * (frmTips.Height + 10)); 170 break; 171 case ContentAlignment.TopLeft: 172 frmTips.Location = new Point(10, 10 + (i + 1) * (frmTips.Height + 10)); 173 break; 174 case ContentAlignment.TopRight: 175 frmTips.Location = new Point(size.Width - frmTips.Width - 10, 10 + (i + 1) * (frmTips.Height + 10)); 176 break; 177 default: 178 break; 179 } 180 })); 181 } 182 else 183 { 184 switch (item.Key.ShowAlign) 185 { 186 case ContentAlignment.BottomCenter: 187 frmTips.Location = new Point((size.Width - frmTips.Width) / 2, size.Height - 100 - (i + 1) * (frmTips.Height + 10)); 188 break; 189 case ContentAlignment.BottomLeft: 190 frmTips.Location = new Point(10, size.Height - 100 - (i + 1) * (frmTips.Height + 10)); 191 break; 192 case ContentAlignment.BottomRight: 193 frmTips.Location = new Point(size.Width - frmTips.Width - 10, size.Height - 100 - (i + 1) * (frmTips.Height + 10)); 194 break; 195 case ContentAlignment.MiddleCenter: 196 frmTips.Location = new Point((size.Width - frmTips.Width) / 2, size.Height - (size.Height - list.Count * (frmTips.Height + 10)) / 2 - (i + 1) * (frmTips.Height + 10)); 197 break; 198 case ContentAlignment.MiddleLeft: 199 frmTips.Location = new Point(10, size.Height - (size.Height - list.Count * (frmTips.Height + 10)) / 2 - (i + 1) * (frmTips.Height + 10)); 200 break; 201 case ContentAlignment.MiddleRight: 202 frmTips.Location = new Point(size.Width - frmTips.Width - 10, size.Height - (size.Height - list.Count * (frmTips.Height + 10)) / 2 - (i + 1) * (frmTips.Height + 10)); 203 break; 204 case ContentAlignment.TopCenter: 205 frmTips.Location = new Point((size.Width - frmTips.Width) / 2, 10 + (i + 1) * (frmTips.Height + 10)); 206 break; 207 case ContentAlignment.TopLeft: 208 frmTips.Location = new Point(10, 10 + (i + 1) * (frmTips.Height + 10)); 209 break; 210 case ContentAlignment.TopRight: 211 frmTips.Location = new Point(size.Width - frmTips.Width - 10, 10 + (i + 1) * (frmTips.Height + 10)); 212 break; 213 default: 214 break; 215 } 216 } 217 218 } 219 } 220 } 221 } 222 #endregion 223 224 public static FrmTips ShowTipsSuccess(Form frm, string strMsg) 225 { 226 return FrmTips.ShowTips(frm, strMsg, 3000, false, ContentAlignment.BottomCenter, null, TipsSizeMode.Large, null, TipsState.Success); 227 } 228 229 public static FrmTips ShowTipsError(Form frm, string strMsg) 230 { 231 return FrmTips.ShowTips(frm, strMsg, 3000, false, ContentAlignment.BottomCenter, null, TipsSizeMode.Large, null, TipsState.Error); 232 } 233 234 public static FrmTips ShowTipsInfo(Form frm, string strMsg) 235 { 236 return FrmTips.ShowTips(frm, strMsg, 3000, false, ContentAlignment.BottomCenter, null, TipsSizeMode.Large, null, TipsState.Info); 237 } 238 public static FrmTips ShowTipsWarning(Form frm, string strMsg) 239 { 240 return FrmTips.ShowTips(frm, strMsg, 3000, false, ContentAlignment.BottomCenter, null, TipsSizeMode.Large, null, TipsState.Warning); 241 }
一些事件處理
1 private void FrmTips_FormClosing(object sender, FormClosingEventArgs e) 2 { 3 if (m_lastTips.Value == this) 4 m_lastTips = new KeyValuePair<string, FrmTips>(); 5 m_lstTips.Remove(this); 6 ReshowTips(); 7 8 for (int i = Application.OpenForms.Count - 1; i >= 0; i--) 9 { 10 if (Application.OpenForms[i].IsDisposed || !Application.OpenForms[i].Visible || Application.OpenForms[i] is FrmTips) 11 { 12 continue; 13 } 14 else 15 { 16 Timer t = new Timer(); 17 t.Interval = 100; 18 var frm = Application.OpenForms[i]; 19 t.Tick += (a, b) => 20 { 21 t.Enabled = false; 22 if (!frm.IsDisposed) 23 ControlHelper.SetForegroundWindow(frm.Handle); 24 }; 25 t.Enabled = true; 26 break; 27 } 28 } 29 } 30 31 private void FrmTips_Load(object sender, EventArgs e) 32 { 33 if (m_CloseTime > 0) 34 { 35 this.timer1.Interval = m_CloseTime; 36 this.timer1.Enabled = true; 37 } 38 } 39 40 private void timer1_Tick(object sender, EventArgs e) 41 { 42 this.timer1.Enabled = false; 43 this.Close(); 44 } 45 46 private void btnClose_MouseDown(object sender, MouseEventArgs e) 47 { 48 this.timer1.Enabled = false; 49 this.Close(); 50 } 51 private void FrmTips_FormClosed(object sender, FormClosedEventArgs e) 52 { 53 this.Dispose(); 54 GC.Collect(); 55 }
最後看一下完整代碼
1 // 版權所有 黃正輝 交流群:568015492 QQ:623128629 2 // 文件名稱:FrmTips.cs 3 // 創建日期:2019-08-15 16:04:54 4 // 功能描述:FrmTips 5 // 項目地址:https://gitee.com/kwwwvagaa/net_winform_custom_control 6 using System; 7 using System.Collections.Generic; 8 using System.ComponentModel; 9 using System.Data; 10 using System.Drawing; 11 using System.Linq; 12 using System.Text; 13 using System.Windows.Forms; 14 15 namespace HZH_Controls.Forms 16 { 17 public partial class FrmTips : FrmBase 18 { 19 private ContentAlignment m_showAlign = ContentAlignment.BottomLeft; 20 21 /// <summary> 22 /// 顯示位置 23 /// </summary> 24 public ContentAlignment ShowAlign 25 { 26 get { return m_showAlign; } 27 set { m_showAlign = value; } 28 } 29 30 private static List<FrmTips> m_lstTips = new List<FrmTips>(); 31 32 private int m_CloseTime = 0; 33 34 public int CloseTime 35 { 36 get { return m_CloseTime; } 37 set 38 { 39 m_CloseTime = value; 40 if (value > 0) 41 timer1.Interval = value; 42 } 43 } 44 45 public FrmTips() 46