概述,上次我们介绍了半遮挡式的遮罩层,本次我们介绍整个窗体的遮盖层,在winform中我们也完成这样的操作,提高用户的体验感和操作性,避免不必要的操作.
首先,我们需要新建一个窗体,做如下设置,如下代码:
1: namespace FlexGridLoading
2: {
3: public partial class FrmProcessing : Form
4: {
5: private static Image m_Image = null;
6: private EventHandler evtHandler = null;
7: private ParameterizedThreadStart workAction = null;
8: private object workActionArg = null;
9: private Thread workThread = null;
10: public string Message
11: {
12: get
13: {
14: return lbMessage.Text;
15: }
16: set
17: {
18: lbMessage.Text = value;
19: }
20: }
21:
22: public bool WorkCompleted = false;
23: public Exception WorkException
24: { get; private set; }
25: public void SetWorkAction(ParameterizedThreadStart workAction, object arg)
26: {
27: this.workAction = workAction;
28: this.workActionArg = arg;
29: }
30:
31: public FrmProcessing(string msg)
32: {
33: InitializeComponent();
34: this.Message = msg;
35: }
36:
37: protected override void OnPaint(PaintEventArgs e)
38: {
39: base.OnPaint(e);
40:
41: if (m_Image != null)
42: {
43: //获得当前gif动画下一步要渲染的帧。
44: UpdateImage();
45:
46: //将获得的当前gif动画需要渲染的帧显示在界面上的某个位置。
47: int x = (int)(panImage.ClientRectangle.Width - m_Image.Width) / 2;
48: int y = 0;
49: //e.Graphics.DrawImage(m_Image, new Rectangle(x, y, m_Image.Width, m_Image.Height));
50: panImage.CreateGraphics().DrawImage(m_Image, new Rectangle(x, y, m_Image.Width, m_Image.Height));
51: }
52: if (this.WorkCompleted)
53: {
54: this.Close();
55: }
56: }
57: private void FrmProcessing_Load(object sender, EventArgs e)
58: {
59: if (this.Owner != null)
60: {
61: this.StartPosition = FormStartPosition.Manual;
62: this.Location = new Point(this.Owner.Left, this.Owner.Top);
63: //MessageBox.Show(string.Format("X={0},Y={1}", this.Owner.Left, this.Owner.Top));
64: this.Width = this.Owner.Width;
65: this.Height = this.Owner.Height;
66: }
67: else
68: {
69: Rectangle screenRect = Screen.PrimaryScreen.WorkingArea;
70: this.Location = new Point((screenRect.Width - this.Width) / 2, (screenRect.Height - this.Height) / 2);
71: }
72:
73: //为委托关联一个处理方法
74: evtHandler = new EventHandler(OnImageAnimate);
75:
76: if (m_Image == null)
77: {
78: Assembly assy = Assembly.GetExecutingAssembly();
79: //获取要加载的gif动画文件
80: m_Image = FlexGridLoading.Properties.Resources.loading; ;
81: }
82: //调用开始动画方法
83: BeginAnimate();
84: }
85:
86:
87: //开始动画方法
88:
89: private void BeginAnimate()
90: {
91: if (m_Image != null)
92: {
93: //当gif动画每隔一定时间后,都会变换一帧,那么就会触发一事件,该方法就是将当前image每变换一帧时,都会调用当前这个委托所关联的方法。
94: ImageAnimator.Animate(m_Image, evtHandler);
95: }
96: }
97:
98: //委托所关联的方法
99:
100: private void OnImageAnimate(Object sender, EventArgs e)
101: {
102: //该方法中,只是使得当前这个winform重绘,然后去调用该winform的OnPaint()方法进行重绘)
103: this.Invalidate();
104: }
105:
106: //获得当前gif动画的下一步需要渲染的帧,当下一步任何对当前gif动画的操作都是对该帧进行操作)
107:
108: private void UpdateImage()
109: {
110: ImageAnimator.UpdateFrames(m_Image);
111: }
112:
113: //关闭显示动画,该方法可以在winform关闭时,或者某个按钮的触发事件中进行调用,以停止渲染当前gif动画。
114:
115: private void StopAnimate()
116: {
117: m_Image = null;
118: ImageAnimator.StopAnimate(m_Image, evtHandler);
119: }
120:
121: private void FrmProcessing_Shown(object sender, EventArgs e)
122: {
123: if (this.workAction != null)
124: {
125: workThread = new Thread(ExecWorkAction);
126: workThread.IsBackground = true;
127: workThread.Start();
128: }
129: }
130:
131: private void ExecWorkAction()
132: {
133: try
134: {
135: var workTask = new Task((arg) =>
136: {
137: this.workAction(arg);
138: },
139: this.workActionArg);
140:
141: workTask.Start();
142: Task.WaitAll(workTask);
143: }
144: catch (Exception ex)
145: {
146: this.WorkException = ex;
147: }
148: finally
149: {
150: this.WorkCompleted = true;
151: }
152:
153: }
154: }
155: }
然后,为了我们方便调用不用在每个页面调用时去new并且设置很多属性,我们需要调用一个通用的Command类
1: namespace FlexGridLoading
2: {
3: public static class Common
4: {
5:
6: public static void ShowProcessing(string msg, Form owner, ParameterizedThreadStart work, object workArg = null)
7: {
8: FrmProcessing processingForm = new FrmProcessing(msg);
9: dynamic expObj = new ExpandoObject();
10: expObj.Form = processingForm;
11: expObj.WorkArg = workArg;
12: processingForm.SetWorkAction(work, expObj);
13: processingForm.ShowDialog(owner);
14: if (processingForm.WorkException != null)
15: {
16: throw processingForm.WorkException;
17: }
18: }
19:
20:
21: }
22: }
1: private void button1_Click(object sender, EventArgs e)
2: {
3: Common.ShowProcessing("正在处理中,请稍候...", this, (obj) =>
4: {
5: //这里写处理耗时的代码,代码处理完成则自动关闭该窗口
6: Thread.Sleep(5000);
7: }, null);
8: }
如果你有疑问,可以到GCDN获得技术支持:
http://gcdn.grapecity.com.cn/showforum-68.html
GCDN:http://gcdn.grapecity.com.cn/
官方网站:/developer