0

我的 WinForms 应用程序的主窗口加载速度很慢(最多 20 秒,具体取决于参数),因此它需要启动屏幕。

主窗口构造函数很慢,因为它执行了数千行代码(其中一些超出了我的影响)。有时此代码会弹出消息框。

我尝试了两种启动画面设计,它们都有问题。有更好的想法吗?

带有 BackgroundWorker 的启动画面

static void Main(string[] args)
{
    var splash = !args.Contains("--no-splash");
    if (splash)
    {
        var bw = new BackgroundWorker();
        bw.DoWork += (sender, eventArgs) => ShowSplash();
        bw.RunWorkerAsync();
    }

    var app = new FormMain(args); // slow. sometimes opens blocking message boxes.
    Application.Run(app);
}

private static void ShowSplash()
{
    using (var splash = new FormSplash())
    {
        splash.Show();
        splash.Refresh();
        Thread.Sleep(TimeSpan.FromSeconds(2));
    }
}

问题:

  1. 启动画面有时会在主窗口打开之前过期(用户认为应用程序已崩溃)
  2. 飞溅关闭时,主窗口有时会最小化。

带有 WindowsFormsApplicationBase 的启动画面

sealed class App : WindowsFormsApplicationBase
{
    protected override void OnCreateSplashScreen()
    {
        this.SplashScreen = new FormSplash();
    }

    protected override void OnCreateMainForm()
    {
        // slow. sometimes opens blocking message boxes.
        this.MainForm = new FormMain(this.CommandLineArgs);
    }
}

问题:

  1. 任何打开的 MessageBoxes 都会默默地出现在启动屏幕后面。用户不会注意到它并认为应用程序卡住了。
  2. 如果启动画面“始终在顶部”,则消息框不可访问且不可点击。
4

3 回答 3

3

我同意 Hans Passant 的观点,即代码需要重新评估,因为设计似乎不正确。

至于手头的问题,您应该能够通过创建自己的 messageBox 实例来解决这个问题。

我使用此代码进行了测试;

public DialogResult TopMostMessageBox(string message, string title, MessageBoxButtons button, MessageBoxIcon icon)
    {
        return DisplayMessageBox(message, title, button, icon);
    }

public DialogResult DisplayMessageBox(string message, string title, MessageBoxButtons buttons, MessageBoxIcon icon)
    {
        DialogResult result;
        using (var topmostForm = new Form {Size = new System.Drawing.Size(1, 1), StartPosition = FormStartPosition.Manual})
        {
            var rect = SystemInformation.VirtualScreen;
            topmostForm.Location = new System.Drawing.Point(rect.Bottom + 10, rect.Right + 10);
            topmostForm.Show();
            topmostForm.Focus();
            topmostForm.BringToFront();
            topmostForm.TopMost = true;
            result = MessageBox.Show(topmostForm, message, title, buttons, icon);
            topmostForm.Dispose();
        }
        //You might not need all these properties...
        return result;
    }
//Usage
TopMostMessageBox("Message","Title" MessageBoxButtons.YesNo, MessageBoxIcon.Question)

再次,我需要强调我同意原始代码需要被重构,并且只是为这个问题提供了一个可能的解决方案。

希望这可以帮助?

于 2013-08-05T11:16:07.537 回答
0

您可以实现我们自己的消息框并使用TopMost属性,TopMost您将在启动屏幕加载器前面获得消息。

有关 topmost 的更多信息:http: //msdn.microsoft.com/en-us/library/system.windows.forms.form.topmost.aspx

于 2013-08-05T10:59:23.587 回答
-1

最后,将慢速代码从构造函数移至 OnShown 事件的处理程序。

正如 Hans Passant 建议的那样,用于WindowsFormsApplicationBase启动屏幕,仔细检查剩余的构造函数代码以确保它永远不会打开消息框。

于 2013-08-08T13:48:49.313 回答