C#如何从后台工作者那里获得完整的表格? [英] C# how do I get a form from a backgroundworker to show completely?

查看:77
本文介绍了C#如何从后台工作者那里获得完整的表格?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

I'm writing a C# WinForms app in VS 2017Professional and I'm having trouble getting a "progress form" to show up on the screen completely. It has a label and a picturebox playing an animated GIF. This form is run from a backgroundworker.

For the most part, it's working fine, except that the progress form that shows while a file is being opened on the main form looks like a light gray rectangle. Inside of it there is a small rectangle at the top outlining where a label is supposed to show and a larger rectangle below it where the picturebox is supposed to show. I'd upload an image of it if I could. How do I get the whole progress form and its controls to show up completely?







Update: I started this project in VS 2013 Ultimate and now I'm working on it in VS 2017 Pro. I simply started working on it in VS 2017. No sign of trouble in the process, though.





我尝试过的:





What I have tried:

Here's the code I'm working with. It's from the main form running on the UI thread: 




private void OpenGame(string filepath)
{
    try
    {
        BackgroundWorker BgwSP = new BackgroundWorker();
        BgwSP.WorkerReportsProgress = BgwSP.WorkerSupportsCancellation = true;
        BgwSP.DoWork += BgwSP_DoWork;
        BgwSP.RunWorkerCompleted += BgwSP_RunWorkerCompleted;
        BgwSP.RunWorkerAsync(filepath);

        // Now set up the filestream andn binaryreader to read the contents of the file.
        FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read);
        BinaryReader br = new BinaryReader(fs);

        // Next we get the Game Info and load it all into the GameInfo class.
        GameInfo.strGameVersion = br.ReadString();
        if (GameInfo.strGameVersion == "1.0" || (GameInfo.strGameVersion == "2.0" && GameInfo.strGameVersion == "Standard Game Project"))
        {
            this.BackColor = SystemColors.AppWorkspace;
            clsOpenStandardGame OpenStandardGame = new clsOpenStandardGame();
            OpenStandardGame.OpenStdGame(filepath);
            this.GameInfo = OpenStandardGame.ReturnGameInfo();
            this.lstQuestions = OpenStandardGame.ReturnlstStdQuestions();
            this.Tiebreaker = OpenStandardGame.ReturnTiebreaker();
        }
        else if (GameInfo.strGameVersion == "2.0" && GameInfo.strGameType == "Multi-Category Game Project")
        {
            this.BackColor = SystemColors.AppWorkspace;
            clsOpenMultiCategoryGame OpenMultiCatGame = new clsOpenMultiCategoryGame();
            OpenMultiCatGame.OpenMultiCatGame(filepath);
            this.GameInfo = OpenMultiCatGame.ReturnGameInfo();
            this.lstCategories = OpenMultiCatGame.ReturnlstCategories();
            this.Tiebreaker = OpenMultiCatGame.ReturnMultiCatTiebreaker();
        }

        // Set up the Intro Screen's mode to Full Screen or Normal Screen.
        if (Properties.Settings.Default.blFullScreenOnGameOpened == true)
            tsbtnFullScreen.PerformClick();

        // Now we set up the title at the top of the main form.
        this.Text = Path.GetFileNameWithoutExtension(filepath).ToString() + " - Trivia Player v2.0";

        // Fix the status strip.
        tslblStatus.Text = "Ready";
        ssStatusStrip.Refresh();

        // And finally, set up the game and prepare to play it.
        SetUpTheGame();
    }
    catch (Exception ex)
    {
        // Suddenly, something went terribly wrong!
        MessageBox.Show(ex.ToString(), "oops.", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

private void BgwSP_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    // OK, the game is done opening, now kill the progress form.
    foreach (frmShowProgress frm in this.OwnedForms)
    {
        if (frm is frmShowProgress)
            frm.Dispose();
    }
}

private void BgwSP_DoWork(object sender, DoWorkEventArgs e)
{
    // Get the filename.
    string strFilepath = Path.GetFileNameWithoutExtension((string)e.Argument);

    // Now show the progress form.
    frmShowProgress frmSP = new frmShowProgress(strFilepath);
    frmSP.BringToFront();
    frmSP.Show();

    // Now let's goof off until we have to close the progress form.
    BackgroundWorker worker = sender as BackgroundWorker;

    for (int i = 0; i <= 100; i++)
    {
        worker.ReportProgress(i);
        Thread.Sleep(100);

        if (worker.CancellationPending && worker.IsBusy)
        {
            frmSP.Dispose();
            e.Cancel = true;
            return;
        }
    }
}

推荐答案

简单,你没有。



必须始终在UI线程(启动线程)上创建和访问任何UI元素,表单,控件和设置/获取其属性。您不能从任何其他线程(包括BackGroundWorker内部)执行此操作。



您可以通过BackgroundWorker的ProgressChanged事件发送进度更新。
Simple, you don't.

Any UI element, Forms, controls, and setting/getting their properties MUST ALWAYS be created and accessed on the UI thread (startup thread). You cannot do it from any other thread, including inside a BackGroundWorker.

You can send progress updates via the ProgressChanged event of the BackgroundWorker.

这篇关于C#如何从后台工作者那里获得完整的表格?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆