添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《 阿里云开发者社区用户服务协议 》和 《 阿里云开发者社区知识产权保护指引 》。如果您发现本社区中有涉嫌抄袭的内容,填写 侵权投诉表单 进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。 原文: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