本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《
阿里云开发者社区用户服务协议
》和
《
阿里云开发者社区知识产权保护指引
》。如果您发现本社区中有涉嫌抄袭的内容,填写
侵权投诉表单
进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
原文:WPF 利用子线程弹出子窗体的研究 一般来说子线程都是用来处理数据的,主窗体用来实现展现,但是有些时候我们希望子窗体实现等待效果,遮挡主窗体并使主窗体逻辑正常进行,这个业务需求虽然不多,但是正好我们用到了,于是我打算把研究成果写在这了。
WPF 利用子线程弹出子窗体的研究
一般来说子线程都是用来处理数据的,主窗体用来实现展现,但是有些时候我们希望子窗体实现等待效果,遮挡主窗体并使主窗体逻辑正常进行,这个业务需求虽然不多,但是正好我们用到了,于是我打算把研究成果写在这了。稍后我会上传我的代码,包含测试程序以及之前两边博文谈到的控件,这里我还实现了一个类似雷达扫描的等待窗体,大家可以稍后查看。
实际上这里只有两个难点需要处理,一个就是如何让子窗体遮挡主窗体并位于主窗体中间,另一个就是委托及跨线程访问UI界面。为了方便调用,我在这里写了一个静态的子线程窗体管理类DialogWindowsManager。
1.遮挡主窗体
大家都知道,showDialog方法就是最好的遮挡效果,但是由于它是线程阻塞的,因此每当我们想到这里的时候会有一个误区,认为调用showDialog一定会阻塞前台界面,其实这里的阻塞只是阻塞调用方法所在的线程,并不是一定会阻塞主线程,因此在子线程中调用showDialog方法即可达到效果。实际测试时发现遮挡效果确实有了,可惜每次showDialog的时候窗体会满屏幕乱飞,好吧,最好的方法当然是设置onwer,不过我一直没尝试成功,因为主窗体与子窗体一直处于两个线程中,最后我通过一个算法将位置计算出来之后赋值给了子窗体。代码如下:
3
///
</summary>
4
public
static
void
ShowWaitingForm(Window onwer) {
5
double
[] d =
new
double
[
2
];
6
d[
0
] = onwer.Top + onwer.Height /
2
-
50
;
7
d[
1
] = onwer.Left + onwer.Width /
2
-
50
;
8
if
(WaitingFormThread ==
null
)
10
WaitingFormThread =
new
Thread(
new
ParameterizedThreadStart(showWaitingForm));
11
WaitingFormThread.SetApartmentState(ApartmentState.STA);
12
WaitingFormThread.Start(d);
13
}
14
else
{
15
CloseWaitingForm();
16
ShowWaitingForm(onwer);
17
}
View Code
2.跨线程访问
这里不得不说WPF还是很给力的,因为它提供了Dispatcher来获取当前要更新的线程,这里网上资料很多,我就不多做解释了,直接上代码:
3
///
</summary>
4
///
<param name="d">
百分比
</param>
5
public
static
void
setProgrssFormPercent(
double
d) {
6
if
(cf !=
null
) {
7
cf.Dispatcher.BeginInvoke(
new
Action(() => {
if
(cf !=
null
) { cf.setPercent(d); } }));
8
Thread.Sleep(
50
);
View Code
3.注意事项
子线程也是UI线程,因此线程一定要设置为ApartmentState.STA状态。
完成的线程管理代码如下:
43
private
static
void
showWaitingForm(
object
o)
44
{
45
double
[] d = (
double
[])o;
46
WaitingForm wf =
new
WaitingForm();
47
wf.WindowStartupLocation =
WindowStartupLocation.Manual;
48
wf.Top = d[
0
];
49
wf.Left = d[
1
];
50
wf.ShowDialog();
51
}
53
///
<summary>
54
///
打开进度条窗体方法
55
///
</summary>
56
///
<param name="o">
显示位置集合 double[] 0-Top 1-Left
</param>
57
private
static
void
showCircleProgressForm(
object
o)
58
{
59
double
[] d = (
double
[])o;
60
cf =
new
CircleProgressForm();
61
cf.WindowStartupLocation =
WindowStartupLocation.Manual;
62
cf.Top = d[
0
];
63
cf.Left = d[
1
];
64
cf.ShowDialog();
65
}
67
///
<summary>
68
///
打开进度条窗体方法
69
///
</summary>
70
///
<param name="o">
显示位置集合 double[] 0-Top 1-Left
</param>
71
private
static
void
showWaitingAndProgressForm(
object
o)
72
{
73
object
[] m = (
object
[])o;
74
double
[] d = (
double
[])m[
0
];
75
wpf =
new
WaitingAndProgressForm();
76
wpf.MainControl.ShowType = (WaitAndProgressType)m[
1
];
77
wpf.WindowStartupLocation =
WindowStartupLocation.Manual;
78
wpf.Top = d[
0
];
79
wpf.Left = d[
1
];
80
wpf.ShowDialog();
81
}
83
#endregion
85
#region
公有方法
87
///
<summary>
88
///
打开等待窗体线程
89
///
</summary>
90
public
static
void
ShowWaitingForm(Window onwer) {
91
double
[] d =
new
double
[
2
];
92
d[
0
] = onwer.Top + onwer.Height /
2
-
50
;
93
d[
1
] = onwer.Left + onwer.Width /
2
-
50
;
94
if
(WaitingFormThread ==
null
)
95
{
96
WaitingFormThread =
new
Thread(
new
ParameterizedThreadStart(showWaitingForm));
97
WaitingFormThread.SetApartmentState(ApartmentState.STA);
98
WaitingFormThread.Start(d);
99
}
100
else
{
101
CloseWaitingForm();
102
ShowWaitingForm(onwer);
103
}
104
}
106
///
<summary>
107
///
关闭等待窗体线程
108
///
</summary>
109
public
static
void
CloseWaitingForm()
110
{
111
WaitingFormThread.Abort();
112
WaitingFormThread.Join();
113
WaitingFormThread.DisableComObjectEagerCleanup();
114
WaitingFormThread =
null
;
115
}
117
///
<summary>
118
///
打开进度条窗体线程
119
///
</summary>
120
public
static
void
ShowCircleProgressForm(Window onwer)
121
{
122
double
[] d =
new
double
[
2
];
123
d[
0
] = onwer.Top + onwer.Height /
2
-
50
;
124
d[
1
] = onwer.Left + onwer.Width /
2
-
50
;
125
if
(CircleProgressFormThread ==
null
)
126
{
127
CircleProgressFormThread =
new
Thread(
new
ParameterizedThreadStart(showCircleProgressForm));
128
CircleProgressFormThread.SetApartmentState(ApartmentState.STA);
129
CircleProgressFormThread.Start(d);
130
Thread.Sleep(
100
);
131
}
132
else
133
{
134
CloseCircleProgressForm();
135
ShowCircleProgressForm(onwer);
136
}
137
}
139
///
<summary>
140
///
设置进度条百分比
141
///
</summary>
142
///
<param name="d">
百分比
</param>
143
public
static
void
setProgrssFormPercent(
double
d) {
144
if
(cf !=
null
) {
145
cf.Dispatcher.BeginInvoke(
new
Action(() => {
if
(cf !=
null
) { cf.setPercent(d); } }));
146
Thread.Sleep(
50
);
147
}
148
}
150
///
<summary>
151
///
关闭进度条窗体线程
152
///
</summary>
153
public
static
void
CloseCircleProgressForm()
154
{
155
CircleProgressFormThread.Abort();
156
CircleProgressFormThread.Join();
157
CircleProgressFormThread.DisableComObjectEagerCleanup();
158
CircleProgressFormThread =
null
;
159
cf =
null
;
160
}
162
///
<summary>
163
///
打开等待进度条窗体线程
164
///
</summary>
165
public
static
void
ShowWaitingAndProgressForm(Window onwer,WaitAndProgressType t)
166
{
167
object
[] o =
new
object
[
2
];
168
double
[] d =
new
double
[
2
];
169
d[
0
] = onwer.Top + onwer.Height /
2
-
50
;
170
d[
1
] = onwer.Left + onwer.Width /
2
-
50
;
171
o[
0
] =
d;
172
o[
1
] =
t;
173
if
(WaitingAndProgressFormThread ==
null
)
174
{
175
WaitingAndProgressFormThread =
new
Thread(
new
ParameterizedThreadStart(showWaitingAndProgressForm));
176
WaitingAndProgressFormThread.SetApartmentState(ApartmentState.STA);
177
WaitingAndProgressFormThread.Start(o);
178
Thread.Sleep(
100
);
179
}
180
else
181
{
182
CloseWaitingAndProgressForm();
183
ShowWaitingAndProgressForm(onwer,t);
184
}
185
}
187
///
<summary>
188
///
设置进度条百分比
189
///
</summary>
190
///
<param name="d">
百分比
</param>
191
public
static
void
setWaitingAndProgressFormPercent(
double
d)
192
{
193
if
(wpf !=
null
)
194
{
195
wpf.Dispatcher.BeginInvoke(
new
Action(() => {
if
(wpf !=
null
) { wpf.setPercent(d); } }));
196
Thread.Sleep(
50
);
197
}
198
}
200
///
<summary>
201
///
关闭等待进度条窗体线程
202
///
</summary>
203
public
static
void
CloseWaitingAndProgressForm()
204
{
205
WaitingAndProgressFormThread.Abort();
206
WaitingAndProgressFormThread.Join();
207
WaitingAndProgressFormThread.DisableComObjectEagerCleanup();
208
WaitingAndProgressFormThread =
null
;
209
wpf =
null
;
210
}
212
#endregion
213
}
214
}
View Code
整个解决方案我会上传的!!
如果喜欢我的文章可以粉我!!!
本文系本人原创,源代码及文章引用转载请注明出处!!谢谢!
源码下载地址:http://files.cnblogs.com/files/lgmbk/UserControlTest.zip