日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

Winform应用程序实现通用遮罩层二

發(fā)布時(shí)間:2025/4/14 62 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Winform应用程序实现通用遮罩层二 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

之前先后發(fā)表過(guò):《Winform應(yīng)用程序?qū)崿F(xiàn)通用遮罩層》、《Winform應(yīng)用程序?qū)崿F(xiàn)通用消息窗口》,這兩款遮罩層其實(shí)都是基于彈出窗口的,今天為大家分享一個(gè)比較簡(jiǎn)單但界面相對(duì)友好的另一種實(shí)現(xiàn)方案,廢話不多說(shuō),直接進(jìn)入主題。

一、實(shí)現(xiàn)思路(解決問(wèn)題順序):

透明遮罩:

1.實(shí)現(xiàn)可設(shè)置透明的Panel控件(MaskPanel);

2.Panel控件(MaskPanel)能夠覆蓋父容器(一般是當(dāng)前窗體form對(duì)象)客戶(hù)區(qū)區(qū)域(即:與父容器客戶(hù)區(qū)區(qū)域大小相同),并處于最上層,保證父容器上的任何控件都被蓋住并保證不可用;

3.Panel控件(MaskPanel)必需實(shí)現(xiàn)隨著父容器大小的改變而改變;

4.Panel控件(MaskPanel)上可呈現(xiàn)以表示正在加載的動(dòng)圖或者文字,并且居中;

異步:

實(shí)現(xiàn)的方法有很多,比如異步委托、Task等,而這是在winform項(xiàng)目中,此次就直接使用BackgroundWorker

二、關(guān)鍵解決方案:

1.可設(shè)置透明控件:通過(guò)自定義控件,并重寫(xiě)CreateParams(其中:?cp.ExStyle |= 0x00000020;)、OnPaint(其中:labelBorderPen、labelBackColorBrush的Color=Color.FromArgb(_alpha, this.BackColor))兩個(gè)方法即可;

2.能夠覆蓋父容器客戶(hù)區(qū)區(qū)域:this.Size = this.Parent.ClientSize;this.Left = 0;this.Top = 0;

3.隨著父容器大小的改變而改變:this.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom;

4.呈現(xiàn)以表示正在加載的動(dòng)圖或者文字,并且居中:

添加PictureBox,設(shè)置Image為loading.gif動(dòng)圖,SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;?Point Location = new Point(this.Location.X + (this.Width - pictureBox_Loading.Width) / 2, this.Location.Y + (this.Height - pictureBox_Loading.Height) / 2);//居中

好了,最后貼出實(shí)現(xiàn)的源代碼:

MaskPanel:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 public?partial?class?MaskPanel : Control { ????private?System.ComponentModel.Container components =?new?System.ComponentModel.Container(); ????private?bool?_isTransparent =?true;//是否透明 ????[Category("透明"), Description("是否使用透明,默認(rèn)為T(mén)rue")] ????public?bool?IsTransparent ????{ ????????get?{?return?_isTransparent; } ????????set?{ _isTransparent = value; } ????} ????private?int?_alpha = 125;//設(shè)置透明度 ????[Category("透明"), Description("設(shè)置透明度")] ????public?int?Alpha ????{ ????????get?{?return?_alpha; } ????????set?{ _alpha = value; } ????} ????public?MaskPanel(Control parent) ????????:?this(parent, 125) ????{ ????} ????/// <summary> ????/// 初始化加載控件 ????/// </summary> ????/// <param name="Alpha"透明度</param> ????public?MaskPanel(Control parent,?int?alpha) ????{ ????????SetStyle(ControlStyles.Opaque,?true);//設(shè)置背景透明 ????????base.CreateControl(); ????????_alpha = alpha; ????????parent.Controls.Add(this); ????????this.Parent = parent; ????????this.Size =?this.Parent.ClientSize; ????????this.Left = 0; ????????this.Top = 0; ????????this.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom; ????????this.BringToFront(); ????????PictureBox pictureBox_Loading =?new?PictureBox(); ????????pictureBox_Loading.BackColor = System.Drawing.Color.Transparent; ????????pictureBox_Loading.Image = Properties.Resources.loading; ????????pictureBox_Loading.Name =?"pictureBox_Loading"; ????????pictureBox_Loading.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; ????????Point Location =?new?Point(this.Location.X + (this.Width - pictureBox_Loading.Width) / 2,?this.Location.Y + (this.Height - pictureBox_Loading.Height) / 2);//居中 ????????pictureBox_Loading.Location = Location; ????????pictureBox_Loading.Anchor = AnchorStyles.None; ????????this.Controls.Add(pictureBox_Loading); ????????this.Visible =?false; ????} ????protected?override?CreateParams CreateParams ????{ ????????get ????????{ ????????????CreateParams cp =?base.CreateParams; ????????????cp.ExStyle |= 0x00000020;?// 開(kāi)啟 WS_EX_TRANSPARENT,使控件支持透明 ????????????return?cp; ????????} ????} ????protected?override?void?OnPaint(PaintEventArgs pe) ????{ ????????Pen labelBorderPen; ????????SolidBrush labelBackColorBrush; ????????if?(_isTransparent) ????????{ ????????????Color cl = Color.FromArgb(_alpha,?this.BackColor); ????????????labelBorderPen =?new?Pen(cl, 0); ????????????labelBackColorBrush =?new?SolidBrush(cl); ????????} ????????else ????????{ ????????????labelBorderPen =?new?Pen(this.BackColor, 0); ????????????labelBackColorBrush =?new?SolidBrush(this.BackColor); ????????} ????????base.OnPaint(pe); ????????pe.Graphics.DrawRectangle(labelBorderPen, 0, 0,?this.Width,?this.Height); ????????pe.Graphics.FillRectangle(labelBackColorBrush, 0, 0,?this.Width,?this.Height); ????} ????protected?override?void?Dispose(bool?disposing) ????{ ????????if?(disposing) ????????{ ????????????if?(!((components ==?null))) ????????????{ ????????????????components.Dispose(); ????????????} ????????} ????????base.Dispose(disposing); ????} }

?為了實(shí)現(xiàn)通用,同時(shí)保證所有的窗體都有異步執(zhí)行并顯示遮罩效果,故此處采用定義一個(gè)窗體基類(lèi):FormBase,里面定義一個(gè)受保護(hù)的DoWorkAsync方法, 代碼如下:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 public?partial?class?FormBase : Form { ????public?FormBase() ????{ ????????InitializeComponent(); ????????this.StartPosition = FormStartPosition.CenterParent; ????} ????/// <summary> ????/// 多線程異步后臺(tái)處理某些耗時(shí)的數(shù)據(jù),不會(huì)卡死界面 ????/// </summary> ????/// <param name="workFunc">Func委托,包裝耗時(shí)處理(不含UI界面處理),示例:(o)=>{ 具體耗時(shí)邏輯; return 處理的結(jié)果數(shù)據(jù) }</param> ????/// <param name="funcArg">Func委托參數(shù),用于跨線程傳遞給耗時(shí)處理邏輯所需要的對(duì)象,示例:String對(duì)象、JObject對(duì)象或DataTable等任何一個(gè)值</param> ????/// <param name="workCompleted">Action委托,包裝耗時(shí)處理完成后,下步操作(一般是更新界面的數(shù)據(jù)或UI控件),示列:(r)=>{ datagirdview1.DataSource=r; }</param> ????protected?void?DoWorkAsync(Func<object,?object> workFunc,?object?funcArg =?null, Action<object> workCompleted =?null) ????{ ????????var?bgWorkder =?new?BackgroundWorker(); ????????//Form loadingForm = null; ????????Control loadingPan =?null; ????????bgWorkder.WorkerReportsProgress =?true; ????????bgWorkder.ProgressChanged += (s, arg) => ????????{ ????????????if?(arg.ProgressPercentage > 1)?return; ????????????#region Panel模式 ????????????var?result =?this.Controls.Find("loadingPan",?true); ????????????if?(result ==?null?|| result.Length <= 0) ????????????{ ????????????????loadingPan =?new?MaskPanel(this) ????????????????{ ????????????????????Name =?"loadingPan" ????????????????}; ????????????} ????????????else ????????????{ ????????????????loadingPan = result[0]; ????????????} ????????????loadingPan.BringToFront(); ????????????loadingPan.Visible =?true; ????????????#endregion ????????}; ????????bgWorkder.RunWorkerCompleted += (s, arg) => ????????{ ????????????#region Panel模式 ????????????if?(loadingPan !=?null) ????????????{ ????????????????loadingPan.Visible =?false; ????????????} ????????????#endregion ????????????bgWorkder.Dispose(); ????????????if?(workCompleted !=?null) ????????????{ ????????????????workCompleted(arg.Result); ????????????} ????????}; ????????bgWorkder.DoWork += (s, arg) => ????????{ ????????????bgWorkder.ReportProgress(1); ????????????var?result = workFunc(arg.Argument); ????????????arg.Result = result; ????????????bgWorkder.ReportProgress(100); ????????}; ????????bgWorkder.RunWorkerAsync(funcArg); ????} }

使用示例如下:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 private?void?button1_Click(object?sender, EventArgs e) { ????int?startNo = 20; ????button1.Enabled =?false; ????this.DoWorkAsync((o) =>?//耗時(shí)邏輯處理(此處不能操作UI控件,因?yàn)槭窃诋惒街? ????{ ????????int?result = 0; ????????for?(int?i = 1; i <= Convert.ToInt32(o); i++) ????????{ ????????????result += i; ????????????Thread.Sleep(500); ????????} ????????return?result; ????}, startNo, (r) =>?//顯示結(jié)果(此處用于對(duì)上面結(jié)果的處理,比如顯示到界面上) ????{ ????????label1.Text = r.ToString(); ????????button1.Enabled =?true; ????}); }

效果圖就不貼出來(lái)了,大家可以COPY上面的所有代碼,即可測(cè)試出效果。

?2017年3月15日優(yōu)化補(bǔ)充:

為了提高異步加載編碼的方便,特優(yōu)化了DoWorkAsync方法,將返回值由object改為dynamic,這樣就比較方便,直接返回,直接使用

方法簽名如下:

protected void DoWorkAsync(Func<object, dynamic> workFunc, object funcArg = null, Action<dynamic> workCompleted = null)

其余邏輯實(shí)現(xiàn)保持不變。

使用更簡(jiǎn)單,如下圖示:

轉(zhuǎn)載于:https://www.cnblogs.com/sjqq/p/6838548.html

總結(jié)

以上是生活随笔為你收集整理的Winform应用程序实现通用遮罩层二的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。