C#如何从后台工作者那里获得完整的表格? [英] C# how do I get a form from a backgroundworker to show completely?
本文介绍了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屋!
查看全文