透明的加载等待层

在稍微复杂的交互应用中,避免不了耗时的操作,这时候总希望给用户明确的提示,表示程序在运行中暂时不能进行其他操作。显示一个半透明的处于等待状态的遮罩层是很好的方法。在Web应用程序中直接设置Div的透明度然后覆盖操作界面就好,但是Winform的好像并没有提供透明度之类的属性。

1.自定义控件类的实现

  1 using System;
  2 using System.ComponentModel;
  3 using System.Drawing;
  4 using System.Windows.Forms;
  5 
  6 namespace WindowsFormsApplication1
  7 {
  8 
  9     /// <summary>
 10     /// 透明的加载等待层
 11     /// </summary>
 12     [ToolboxBitmap(typeof(LoadingPanel))]
 13     public class LoadingPanel : Control
 14     {
 15         #region Field
 16 
 17         /// <summary>
 18         /// 是否背景透明
 19         /// </summary>
 20         private bool _transparentBackGround = true;
 21 
 22         /// <summary>
 23         /// 透明度
 24         /// </summary>
 25         private int _alpha = 125;
 26 
 27         /// <summary>
 28         /// 容器组件
 29         /// </summary>
 30         private readonly Container _components = new Container();
 31 
 32         #endregion
 33 
 34         #region Property
 35 
 36         /// <summary>
 37         /// 是否使用透明
 38         /// </summary>
 39         [Category("AlphaOpaque"), Description("是否使用透明,默认为True")]
 40         public bool TransparentBackGround
 41         {
 42             get { return _transparentBackGround; }
 43             set
 44             {
 45                 _transparentBackGround = value;
 46                 this.Invalidate();
 47             }
 48         }
 49 
 50         /// <summary>
 51         /// 设置透明度
 52         /// </summary>
 53         [Category("AlphaOpaque"), Description("设置透明度")]
 54         public int Alpha
 55         {
 56             get { return _alpha; }
 57             set
 58             {
 59                 _alpha = value;
 60                 this.Invalidate();
 61             }
 62         }
 63 
 64         #endregion
 65 
 66         #region Ctor
 67 
 68         /// <summary>
 69         /// 构造函数
 70         /// </summary>
 71         public LoadingPanel() : this(true) { }
 72 
 73         /// <summary>
 74         /// 标准构造函数
 75         /// </summary>
 76         /// <param name="showLoadingImage"></param>
 77         public LoadingPanel(bool showLoadingImage)
 78         {
 79             SetStyle(ControlStyles.Opaque | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
 80 
 81             base.CreateControl();
 82             // 显示等待的图像
 83             if (showLoadingImage)
 84             {
 85                 var pictureBoxLoading = new PictureBox();
 86                 pictureBoxLoading.BackColor = Color.White;
 87                 pictureBoxLoading.Image = Properties.Resources.loding;
 88                 pictureBoxLoading.Name = "pictureBox_Loading";
 89                 pictureBoxLoading.Size = new Size(48, 48);
 90                 pictureBoxLoading.SizeMode = PictureBoxSizeMode.Zoom;
 91                 var location = new Point(this.Location.X + (this.Width - pictureBoxLoading.Width) / 2, 
 92                     this.Location.Y + (this.Height - pictureBoxLoading.Height) / 2);
 93                 pictureBoxLoading.Location = location;
 94                 pictureBoxLoading.Anchor = AnchorStyles.None;
 95                 this.Controls.Add(pictureBoxLoading);
 96             }
 97         }
 98 
 99         #endregion
100 
101         #region Override Method
102 
103         /// <summary>
104         /// 自定义绘制窗体
105         /// </summary>
106         /// <param name="e"></param>
107         protected override void OnPaint(PaintEventArgs e)
108         {
109             Pen labelBorderPen;
110             SolidBrush labelBackColorBrush;
111 
112             if (_transparentBackGround)
113             {
114                 Color drawColor = Color.FromArgb(this._alpha, this.BackColor);
115                 labelBorderPen = new Pen(drawColor, 0);
116                 labelBackColorBrush = new SolidBrush(drawColor);
117             }
118             else
119             {
120                 labelBorderPen = new Pen(this.BackColor, 0);
121                 labelBackColorBrush = new SolidBrush(this.BackColor);
122             }
123 
124             float controlWidth = this.Size.Width;
125             float controlHeight = this.Size.Height;
126 
127             e.Graphics.DrawRectangle(labelBorderPen, 0, 0, controlWidth, controlHeight);
128             e.Graphics.FillRectangle(labelBackColorBrush, 0, 0, controlWidth, controlHeight);
129 
130             base.OnPaint(e);
131         }
132 
133         /// <summary>
134         /// 析构处理
135         /// </summary>
136         /// <param name="disposing"></param>
137         protected override void Dispose(bool disposing)
138         {
139             if (disposing)
140             {
141                 if (_components != null)
142                 {
143                     _components.Dispose();
144                 }
145             }
146             base.Dispose(disposing);
147         }
148 
149         #endregion
150 
151         #region Public method
152 
153         /// <summary>
154         /// 隐藏处理
155         /// </summary>
156         internal void CloseWaitingPanel()
157         {
158             this.BeginInvoke(new Action(() =>
159             {
160                 SendToBack();
161                 Hide();
162             }));
163         }
164 
165         /// <summary>
166         /// 显示处理
167         /// </summary>
168         internal void ShowWaitingPanel()
169         {
170             this.BeginInvoke(new Action(() =>
171             {
172                 BringToFront();
173                 Show();
174             }));
175         }
176 
177         #endregion
178     }
179 }

2.在窗体引用遮罩类达到理想的效果

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private readonly LoadingPanel _loadingPanel;

        public Form1()
        {
            InitializeComponent();

            _loadingPanel = new LoadingPanel();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
           _loadingPanel.Dock = DockStyle.Fill;
            _loadingPanel.Hide();
           Controls.Add(_loadingPanel);
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            Thread.Sleep(10 * 1000);
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            _loadingPanel.CloseWaitingPanel();
        }

        private void btnLoad_Click(object sender, EventArgs e)
        {
            if (!backgroundWorker1.IsBusy)
            {
                _loadingPanel.ShowWaitingPanel();

                backgroundWorker1.RunWorkerAsync();
            }
        }

    }
}

可以参考实现的效果,当单击按钮时,遮罩层显示半透明样式显示以遮挡用户操作。当后台操作结果时,遮罩层消失,用户继续其他操作。

原文地址:https://www.cnblogs.com/JustYong/p/5795724.html