zoukankan      html  css  js  c++  java
  • WPF 利用子线程弹出子窗体的研究

      一般来说子线程都是用来处理数据的,主窗体用来实现展现,但是有些时候我们希望子窗体实现等待效果,遮挡主窗体并使主窗体逻辑正常进行,这个业务需求虽然不多,但是正好我们用到了,于是我打算把研究成果写在这了。稍后我会上传我的代码,包含测试程序以及之前两边博文谈到的控件,这里我还实现了一个类似雷达扫描的等待窗体,大家可以稍后查看。

      实际上这里只有两个难点需要处理,一个就是如何让子窗体遮挡主窗体并位于主窗体中间,另一个就是委托及跨线程访问UI界面。为了方便调用,我在这里写了一个静态的子线程窗体管理类DialogWindowsManager。

    1.遮挡主窗体

      大家都知道,showDialog方法就是最好的遮挡效果,但是由于它是线程阻塞的,因此每当我们想到这里的时候会有一个误区,认为调用showDialog一定会阻塞前台界面,其实这里的阻塞只是阻塞调用方法所在的线程,并不是一定会阻塞主线程,因此在子线程中调用showDialog方法即可达到效果。实际测试时发现遮挡效果确实有了,可惜每次showDialog的时候窗体会满屏幕乱飞,好吧,最好的方法当然是设置onwer,不过我一直没尝试成功,因为主窗体与子窗体一直处于两个线程中,最后我通过一个算法将位置计算出来之后赋值给了子窗体。代码如下:

     1 /// <summary>
     2         /// 打开等待窗体线程
     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)
     9             {
    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             }
    18         }
    View Code

    2.跨线程访问

      这里不得不说WPF还是很给力的,因为它提供了Dispatcher来获取当前要更新的线程,这里网上资料很多,我就不多做解释了,直接上代码:

     1 /// <summary>
     2         /// 设置进度条百分比
     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);
     9             }
    10         }
    View Code

    3.注意事项

      子线程也是UI线程,因此线程一定要设置为ApartmentState.STA状态。

    完成的线程管理代码如下:

      1 using System;
      2 using System.Collections.Generic;
      3 using System.Linq;
      4 using System.Text;
      5 using System.Threading;
      6 using System.Windows;
      7 
      8 namespace MyUserControlLibrary
      9 {
     10     public static class DialogWindowsManager
     11     {
     12         #region 属性
     13 
     14         /// <summary>
     15         /// 等待窗体处理线程
     16         /// </summary>
     17         static Thread WaitingFormThread;
     18         /// <summary>
     19         /// 进度条进程
     20         /// </summary>
     21         static Thread CircleProgressFormThread;
     22 
     23         /// <summary>
     24         /// 等待进度条进程
     25         /// </summary>
     26         static Thread WaitingAndProgressFormThread;
     27 
     28         /// <summary>
     29         /// 进度条窗体
     30         /// </summary>
     31         static CircleProgressForm cf;
     32         /// <summary>
     33         /// 等待进度条
     34         /// </summary>
     35         static WaitingAndProgressForm wpf;
     36         #endregion
     37 
     38         #region 私有方法
     39 
     40         /// <summary>
     41         /// 打开等待窗体方法
     42         /// </summary>
     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         }
     52 
     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         }
     66 
     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         }
     82 
     83         #endregion
     84 
     85         #region 公有方法
     86 
     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         }
    105 
    106         /// <summary>
    107         /// 关闭等待窗体线程
    108         /// </summary>
    109         public static void CloseWaitingForm()
    110         {
    111             WaitingFormThread.Abort();
    112             WaitingFormThread.Join();
    113             WaitingFormThread.DisableComObjectEagerCleanup();
    114             WaitingFormThread = null;
    115         }
    116 
    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         }
    138 
    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         }
    149 
    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         }
    161 
    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         }
    186 
    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         }
    199 
    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         }
    211 
    212         #endregion
    213     }
    214 }
    View Code

    整个解决方案我会上传的!!

    如果喜欢我的文章可以粉我!!!

    本文系本人原创,源代码及文章引用转载请注明出处!!谢谢!

    源码下载地址:https://files.cnblogs.com/files/lgmbk/UserControlTest.zip

      

  • 相关阅读:
    HTML5 <input> multiple 属性
    AWS
    new Set() 数组去重
    IAM
    Amazon S3
    Promis 实例
    JS
    React 5
    React 4
    React 3
  • 原文地址:https://www.cnblogs.com/lgmbk/p/5057464.html
Copyright © 2011-2022 走看看