c# – WPF Please Wait Dialog

前端之家收集整理的这篇文章主要介绍了c# – WPF Please Wait Dialog前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在开发一个c#4.0的 WPF桌面应用程序,它必须处理许多长时间运行的操作(从数据库加载数据,计算模拟,优化路由等).

当这些长时间运行的操作在后台运行时,我想显示一个Please-Wait对话框.当显示Please-Wait对话框时,应该锁定应用程序,但只是禁用应用程序窗口不是一个好主意,因为所有DataGrids都将失去其状态(SelectedItem).

到目前为止我的工作但有一些问题:
使用Create-factory方法创建新的WaitXUI. Create方法需要标题文本和对应该锁定的主机控件的引用. Create方法设置窗口的StartupLocation,标题文本和要锁定的主机:

  1. WaitXUI wait = WaitXUI.Create("Simulation running...",this);
  2. wait.ShowDialog(new Action(() =>
  3. {
  4. // long running operation
  5. }));

使用重载的ShowDialog方法,然后可以显示WaitXUI. ShowDialog重载确实需要一个包装长时间运行操作的Action.

在ShowDialog重载中,我只是在自己的线程中启动Action,然后禁用主机控件(将Opacity设置为0.5并将IsEnabled设置为false)并调用基类的ShowDialog.

  1. public bool? ShowDialog(Action action)
  2. {
  3. bool? result = true;
  4.  
  5. // start a new thread to start the submitted action
  6. Thread t = new Thread(new ThreadStart(delegate()
  7. {
  8. // start the submitted action
  9. try
  10. {
  11. Dispatcher.UnhandledException += Dispatcher_UnhandledException;
  12. Dispatcher.Invoke(DispatcherPriority.Normal,action);
  13. }
  14. catch (Exception ex)
  15. {
  16. throw ex;
  17. }
  18. finally
  19. {
  20. // close the window
  21. Dispatcher.UnhandledException -= Dispatcher_UnhandledException;
  22. this.DoClose();
  23. }
  24. }));
  25. t.Start();
  26.  
  27. if (t.ThreadState != ThreadState.Stopped)
  28. {
  29. result = this.ShowDialog();
  30. }
  31. return result;
  32. }
  33.  
  34. private new bool? ShowDialog()
  35. {
  36. DisableHost();
  37. this.Topmost = true;
  38. return base.ShowDialog();
  39. }
  40.  
  41. private void DisableHost()
  42. {
  43. if (host != null)
  44. {
  45. host.Dispatcher.Invoke(new Action(delegate()
  46. {
  47. this.Width = host.Width - 20;
  48. host.Cursor = Cursors.Wait;
  49. host.IsEnabled = false;
  50. host.Opacity = 0.5;
  51. }));
  52. }
  53. }

以下是这个问题:

>禁用主机控件会导致状态信息丢失(SelectedItems …)
>当WaitXUI显示后,当线程结束几毫秒时,WaitXUI有时会显示几毫秒
>有时虽然线程仍在运行,但对话框根本不会出现

这些是我目前想到的主要问题.如何改进这个概念,或者可以采用其他什么方法解决这个问题?

提前致谢!

解决方法

在开发WPF应用程序时,一点横向思维总是有帮助的.只需一个Grid,一个Rectangle,一个bool属性(你已经拥有)和一个BooleanToVisibilityConverter就可以轻松满足你的要求,你不必禁用任何控件.

这个想法很简单.在视图内容添加一个白色矩形,其Opacity属性设置在0.5和0.75之间.数据将其Visibility属性绑定到视图模型或后面的代码中的bool属性,并插入BooleanToVisibilityConverter:

  1. <Grid>
  2. <Grid>
  3. <!--Put your main content here-->
  4. </Grid>
  5. <Rectangle Fill="White" Opacity="0.7" Visibility="{Binding IsWaiting,Converter={StaticResource BoolToVisibilityConverter}}" />
  6. <!--You could add a 'Please Wait' TextBlock here-->
  7. </Grid>

现在,当您想要禁用控件时,只需将bool属性设置为true,Rectangle将使UI显示为淡入淡出:

  1. IsWaiting = true;

猜你在找的C#相关文章