如何修复闪屏后面出现的消息框?

时间:2013-07-31 16:09:18

标签: c# .net winforms

我的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. 主窗口有时会在飞溅关闭时最小化。
  3. 使用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. 任何打开的MessageBox都会出现在启动画面后面。用户不会注意到它并认为应用程序被卡住了。
    2. 如果启动画面“始终位于顶部”,则消息框无法访问且无法点击。

3 个答案:

答案 0 :(得分:1)

我同意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)

同样,我需要强调的是,我同意原始代码需要重新考虑,并且只提供问题的可能解决方案。

希望这有帮助吗?

答案 1 :(得分:0)

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

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

答案 2 :(得分:-1)

最后,将慢速代码从构造函数移动到OnShown event的处理程序。

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