Click here to Skip to main content
15,888,113 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
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: 

C#
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;
        }
    }
}
Posted
Updated 7-Apr-17 8:04am
v2

1 solution

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.
 
Share this answer
 
v2
Comments
Heather Czerniak 6-Apr-17 13:26pm    
Thanks for your response, Dave. In other words, I can just instantiate the frmSP on the UI thread and close it as well, right? I put it in a backgroundworker because I thought that spreading out the to-do's over two threads would 1) speed up execution of code and 2) would take a load off the UI thread.
Dave Kreskowiak 7-Apr-17 15:18pm    
Yes

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900