c# - 加载用户控件时显示 "User control is loading"消息

标签 c# winforms multithreading

我有一个带有 TabStrip 控件的 Winforms 应用程序。在运行时,UserControls 将被动态加载到不同的选项卡中。

我想在加载用户控件之前向用户显示“用户控件 xyz 正在加载”消息(将现有标签设置为可见并更改其文本),直到加载完全完成。

到目前为止我的方法:

  1. 尝试在 BackgroundWorker 线程中加载用户控件。这失败了,因为我必须在加载 UserControl 期间访问 Gui-Controls
  2. 尝试在 BackgroundWorker 线程中显示消息。这显然失败了,因为 BackgroundWorker 线程不是 UI 线程;-)
  3. 显示消息,调用 DoEvents(),加载 UserControl。每次加载 UserControl 时,这都会导致不同的行为(闪烁,...),而且我无法控制何时以及如何将其再次设置为不可见。

总结起来,我有两个问题:

  1. 如何在加载用户控件之前确保消息直接可见
  2. 如何确保消息再次设置为不可见,就在 UserControl 完全加载的那一刻(包括所有数据绑定(bind)、网格格式等)

最佳答案

我们使用的是类似这样的:

  1. 创建一个包含您想向用户显示的任何内容的新表单,
  2. 实现一个静态方法,您可以在其中调用要在其内部创建的表单,以防止内存泄漏
  3. 在此表单中创建一个新线程,以便表单在单独的线程中运行并保持响应;我们使用一个显示进度条填满的 ajax 控件。

在您用来启动线程的方法中,将其属性设置为 topmost true 以确保它保持在顶部。

例如在您的主窗体中执行此操作:

loadingForm.ShowLoadingScreen("usercontrollname");
//do something
loadingform.CloseLoadingScreen();

在加载表单类中;

public LoadingScreen()
{
  InitializeComponent();
}

public static void ShowLoadingScreen(string usercontrollname)
{
  // do something with the usercontroll name if desired
  if (_LoadingScreenThread == null)
  {
    _LoadingScreenThread = new Thread(new ThreadStart(DoShowLoadingScreen));
    _LoadingScreenThread.IsBackground = true;
    _LoadingScreenThread.Start();
  }
}

public static void CloseLoadingScreen()
{
  if (_ls.InvokeRequired)
  {
    _ls.Invoke(new MethodInvoker(CloseLoadingScreen));
  }
  else
  {
    Application.ExitThread();
    _ls.Dispose();
    _LoadingScreenThread = null;
  }
}

private static void DoShowLoadingScreen()
{
    _ls = new LoadingScreen();
    _ls.FormBorderStyle = FormBorderStyle.None;
    _ls.MinimizeBox = false;
    _ls.ControlBox = false;
    _ls.MaximizeBox = false;
    _ls.TopMost = true;
    _ls.StartPosition = FormStartPosition.CenterScreen;

  Application.Run(_ls);
}

关于c# - 加载用户控件时显示 "User control is loading"消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11861701/

相关文章:

java - CyclicBarrier 启动执行不同逻辑的并行线程

c# - ReportViewer 和辅助功能

.net - WinForms RichTextBox : how to reformat asynchronously, 没有触发 TextChanged 事件

c# - CRM 中不同数据类型的计算

c# - 使用 Graphics.FillPath 奇怪地绘制 GraphicsPath

c# - 确定自定义 winforms 控件的设计时上下文

multithreading - 线程本地存储 GCC 编译器

java - 我如何将 ReentrantReadWriteLock.readLock 或 ReentrantReadWriteLock.writeLock 转换为我的类对象

C# 等效于 PowerShell $input 变量

c# - 如何在不重启 AppDomain 的情况下在运行时将模块添加到 MVC4