你的位置:首页 > 软件开发 > ASP.net > Winform应用程序实现通用遮罩层

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

发布时间:2015-04-16 14:01:08
在WEB上,我们在需要进行大数据或复杂逻辑处理时,由于耗时较长,一般我们会在处理过程中的页面上显示一个半透明的遮罩层,上面放个图标或提示:正在处理中...等字样,这样用户体验就比较好了,然而如果在Winform客户端程序,通常遮罩层的处理就显得不那么简单或不那么好看,而我今天要说 ...

在WEB上,我们在需要进行大数据或复杂逻辑处理时,由于耗时较长,一般我们会在处理过程中的页面上显示一个半透明的遮罩层,上面放个图标或提示:正在处理中...等字样,这样用户体验就比较好了,然而如果在Winform客户端程序,通常遮罩层的处理就显得不那么简单或不那么好看,而我今天要说明的是,我实现的这个Winform通用遮罩层,却可以实现类似WEB上的遮罩层,既可以透明,而且还可以显示动态图片以及文字,那如何实现的呢,我现在一一讲解。

首先要明确我们要实现的效果:透明+动态图标+文字

透明:这个简单,只需要将窗体的Opacity设为100%以下的值就可以了,这里我采用85%;

动态图标:这个相对复杂一些,因为Winform目前没有现成的支持直接显示动图的控件,但幸好有一个组件ImageAnimator支持逐帧动画,我们只需要将图片绑定到ImageAnimator的Animate方法上(即:ImageAnimator.Animate(m_Image,EventHandler委托);),然后重写窗体的OnPaint即可,具体的代码实现见下面公布的源码。

文字:这个简单,放在一个Label控件即可

还有为了能够让图标与文字在相对的位置(即不论大小)保持居中,我这里采用了一个TableLayoutPanel,分成两行,上行放置Label,并设为居中,下行放置Panel,提供绘制动图的区域。

完整代码实现如下(部份代码参考网络上它人的文章):

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Draget='_blank'>wing;using System.Linq;using System.Text;using System.Windows.Forms;using System.Reflection;using System.Threading;using System.Threading.Tasks;namespace TEMS{  public partial class FrmProcessing : Form  {    private static Image m_Image = null;    private EventHandler evtHandler = null;    private ParameterizedThreadStart workAction = null;    private object workActionArg = null;    private Thread workThread = null;    public string Message    {      get      {        return lbMessage.Text;      }      set      {        lbMessage.Text = value;      }    }    public bool WorkCompleted = false;    public Exception WorkException    { get; private set; }    public void SetWorkAction(ParameterizedThreadStart workAction, object arg)    {      this.workAction = workAction;      this.workActionArg = arg;    }    public FrmProcessing(string msg)    {      InitializeComponent();      this.Message = msg;    }    protected override void OnPaint(PaintEventArgs e)    {      base.OnPaint(e);      if (m_Image != null)      {        //获得当前gif动画下一步要渲染的帧。        UpdateImage();        //将获得的当前gif动画需要渲染的帧显示在界面上的某个位置。        int x = (int)(panImage.ClientRectangle.Width - m_Image.Width) / 2;        int y = 0;        //e.Graphics.DrawImage(m_Image, new Rectangle(x, y, m_Image.Width, m_Image.Height));        panImage.CreateGraphics().DrawImage(m_Image, new Rectangle(x, y, m_Image.Width, m_Image.Height));      }      if (this.WorkCompleted)      {        this.Close();      }    }    private void FrmProcessing_Load(object sender, EventArgs e)    {      if (this.Owner != null)      {        this.StartPosition = FormStartPosition.Manual;        this.Location = new Point(this.Owner.Left, this.Owner.Top);        //MessageBox.Show(string.Format("X={0},Y={1}", this.Owner.Left, this.Owner.Top));        this.Width = this.Owner.Width;        this.Height = this.Owner.Height;      }      else      {        Rectangle screenRect = Screen.PrimaryScreen.WorkingArea;        this.Location = new Point((screenRect.Width - this.Width) / 2, (screenRect.Height - this.Height) / 2);      }      //为委托关联一个处理方法      evtHandler = new EventHandler(OnImageAnimate);      if (m_Image == null)      {        Assembly assy = Assembly.GetExecutingAssembly();        //获取要加载的gif动画文件        m_Image = Image.FromStream(assy.GetManifestResourceStream(assy.GetName().Name + ".Resources.loading2.gif"));      }      //调用开始动画方法      BeginAnimate();    }    //开始动画方法    private void BeginAnimate()    {      if (m_Image != null)      {        //当gif动画每隔一定时间后,都会变换一帧,那么就会触发一事件,该方法就是将当前image每变换一帧时,都会调用当前这个委托所关联的方法。        ImageAnimator.Animate(m_Image, evtHandler);      }    }    //委托所关联的方法    private void OnImageAnimate(Object sender, EventArgs e)    {      //该方法中,只是使得当前这个winform重绘,然后去调用该winform的OnPaint()方法进行重绘)      this.Invalidate();    }    //获得当前gif动画的下一步需要渲染的帧,当下一步任何对当前gif动画的操作都是对该帧进行操作)    private void UpdateImage()    {      ImageAnimator.UpdateFrames(m_Image);    }    //关闭显示动画,该方法可以在winform关闭时,或者某个按钮的触发事件中进行调用,以停止渲染当前gif动画。    private void StopAnimate()    {      m_Image = null;      ImageAnimator.StopAnimate(m_Image, evtHandler);    }    private void FrmProcessing_Shown(object sender, EventArgs e)    {      if (this.workAction != null)      {        workThread = new Thread(ExecWorkAction);        workThread.IsBackground = true;        workThread.Start();      }    }    private void ExecWorkAction()    {      try      {        var workTask = new Task((arg) =>                {                  this.workAction(arg);                },              this.workActionArg);        workTask.Start();        Task.WaitAll(workTask);      }      catch (Exception ex)      {        this.WorkException = ex;      }      finally      {        this.WorkCompleted = true;      }    }  }}

原标题:Winform应用程序实现通用遮罩层

关键词:winform

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。

可能感兴趣文章

我的浏览记录