【问题标题】:Show Main Form after splash screen completes the background process启动画面完成后台进程后显示主窗体
【发布时间】:2018-08-04 15:55:56
【问题描述】:

是否可以只显示启动画面(不显示主窗体)?

SplashScreen splash;

[STAThread]
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    splash = new SplashScreen();
    splash.Show();

    BackgroundWorker backgroundWorker = new BackgroundWorker();
    backgroundWorker.DoWork += BackgroundWorker_DoWork;
    backgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
    backgroundWorker.RunWorkerAsync();

    // var mainForm = MainForm();
    // Application.Run(layoutForm); // I don't want to call this from here
}


private static void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
     splash.Close();
     // This never gets called, coz application ended
}

private static void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
    for (int i = 0; i <= 100; i++)
    {
        Thread.Sleep(100);
    }
}

【问题讨论】:

  • 至少,您需要调用ShowDialog 而不是Show 并在此之前开始后台处理(假设简单的方法适合您)。
  • 另外,您可能还想使用一些计时器来控制飞溅在快速计算机上最少显示的时间。
  • thnx @Phil1970,似乎 ShowDialog 会为我解决问题..
  • 我需要将我的 BackgroundWorker 代码移动到 SplashScreen Load 事件

标签: c# winforms


【解决方案1】:

您可以从主窗体调用启动画面。

public partial class mainform : Form
{
    public mainform()
    {
        InitializeComponent();
    }

    public mainform_Load(object sender, EventArgs e)
    {
        this.Visible = false;
        using (SplashScreen ss = new SplashScreen())
        {
            ss.ShowDialog();
            SetTheme(ss.LoadedTheme);
            this.Visible = true;
        }
    }

    private void SetTheme(Theme theme)
    {
        //Put your theme setting code here.
    }
}

您的 SplashScreen 代码如下所示:

public partial class SplashScreen : Form
{
    public Theme LoadedTheme { get; private set; }

    public SplashScreen()
    {
        InitializeComponent();
    }

    public void SplashScreen_Load(object sender, EventArgs e)
    {
        bwSplashScreenWorker.RunWorkerAsync();
    }

    public void bwSplashScreenWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        // Load in your data here
        LoadedTheme = LoadTheme();
    }

    public void bwSplashScreenWorker_Completed(object sender, RunWorkerCompletedEventArgs e)
    {
        DialogResult = DialogResult.OK;
    }
}

现在,您的应用程序将启动,当主窗体加载时,它将隐藏自己,以阻塞方式打开 SplashScreen。闪屏将在后台线程中加载您的主题数据并将其保存到 LoadedTheme 属性中。当后台工作人员完成时,它会将 DialogResult 设置为 OK,这会关闭 SplashScreen 并将控制权返回给 mainform_Loaded。此时,您调用从 SplashScreen 传入公共属性 LoadedTheme 的 SetTheme 方法。您的 SetTheme 方法设置了您的主题并返回到 mainform_Loaded,它将主窗体设置为可见。

【讨论】:

  • 在初始屏幕结束加载之前不显示主窗体的全部意义在于,我在 MainForm 的 ctor 中做某事,这取决于启动时加载的数据。 :(
  • 如果您在主表单构造函数中长时间运行,那么您做错了什么。如果它正在加载数据,则在后台工作人员的启动屏幕上执行。
  • 不,我没有在 ctor 中执行任何长时间运行的任务。我正在启动屏幕后台工作人员中执行长时间运行的任务。并使用 MainForm ctor 中的数据。例如。用户选择的主题等
  • 哦,我明白了。那么为什么不在你的初始屏幕关闭之后并且在你将 mainform.Visible 设置为 true 之前在 mainform_Loaded 中执行此操作呢?它会产生相同的效果,但代码会更简洁。我将编辑我的答案以包含此内容。
猜你喜欢
  • 2023-03-27
  • 2012-10-12
  • 2015-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-29
  • 1970-01-01
相关资源
最近更新 更多