C# 进度条窗体未完全加载
我正在写一个程序,可能需要相当多的加载时间(5-30秒)。我希望有一个以字幕风格的进度条开始的表单,这样用户就知道正在做什么C# 进度条窗体未完全加载,c#,winforms,progress-bar,C#,Winforms,Progress Bar,我正在写一个程序,可能需要相当多的加载时间(5-30秒)。我希望有一个以字幕风格的进度条开始的表单,这样用户就知道正在做什么 public FrmMain() { var loading = new FrmLoading(); loading.Show(); InitializeComponent(); // other start up code here loading.Close() } 现在,加载很好地弹出。问题是,标签和进度条显
public FrmMain()
{
var loading = new FrmLoading();
loading.Show();
InitializeComponent();
// other start up code here
loading.Close()
}
现在,加载
很好地弹出。问题是,标签和进度条显示为空,看起来它们几乎崩溃了。我已经调查了后台工作人员
,但是,老实说,我不完全理解如何让它为我工作。我尝试在以下网站上学习教程和示例:
BackgroundWorker
尝试包括创建一个函数,该函数执行在我的FrmMain
中执行的所有操作。所以,我有:
public FrmMain()
{
Loading = new FrmLoading();
Loading.Show();
backgroundWorker1.RunWorkerAsync();
}
private void FormLoading()
{
// Initialize and loading elements of the form
InitializeComponent();
}
private void BackgroundWorker1DoWork(object sender, DoWorkEventArgs e)
{
FormLoading();
}
private void BackgroundWorker1RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Loading.Close();
}
但是我一直在
backgroundWorker1.RunWorkerAsync()上获得NullReferenceException
代码>一个鲜为人知或经常被遗忘的框架库是Microsoft.VisualBasic。你可以在C#应用程序中使用它。只需添加一个引用。。。还有这个班。它处理所有后台工作线程和其他线程
public class MyApplication : WindowsFormsApplicationBase
{
private static MyApplication _application;
public static void Run(Form form)
{
_application = new MyApplication{ MainForm = form };
_application.Run(Environment.GetCommandLineArgs());
}
protected override void OnCreateSplashScreen()
{
this.SplashScreen = new MySplashScreenForm();
}
}
最后,将Program.Main()下的应用程序启动更改为:
到
如果您不熟悉,该类还提供了更多功能,如单实例处理,这些功能绝对值得一看。也许这会有所帮助:
添加一个:
Shown += new EventHandler(Form1_Shown);
在初始化组件()之后代码>
并加上:
void Form1_Shown(object sender, EventArgs e)
{
Refresh();
}
此外,如果您没有在设计器中订阅BackgroundWorker1DoWork
事件处理程序,则必须添加:
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
我最终所做的可能并不优雅,但它完成了我所需要的
public FrmMain()
{
InitializeComponent();
backgroundWorker1.RunWorkerAsync();
var loading = new FrmLoading();
loading.ShowDialog();
}
private void BackgroundWorker1DoWork(object sender, DoWorkEventArgs e)
{
DbQuery();
}
private void BackgroundWorker1RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Loading.Close();
}
这将打开我的加载
表单,使其具有焦点并完全加载。由于我在调用ShowDialog()
之前调用了DoWork
,因此BackgroundWorker
继续工作。一旦DbQuery()
完成,它将调用BackgroundWorker1RunWorkerCompleted()
,这将关闭我的frmload
并继续我的程序。感谢所有发帖的人。这正是使用后台工作人员的情况。请说明您尝试使用该解决方案时遇到的问题。一般的方法很简单。构造函数显示加载窗体,启动后台工作程序,DoWork
事件执行长时间运行的任务,完成的事件关闭加载窗体。在技术上还有其他方法,例如使用任务、异步/等待、直接线程访问等。但是如果您在使用BGW时遇到问题,那么使用这些方法将更困难,而不是更容易。问题是您在主(UI)线程中进行所有处理。当你这样做时,线程就没有机会绘制控件,Windows认为你的应用程序被卡住了。正如@Servy刚刚写的,您应该在后台线程中进行处理(一个BackgroundWorker
适合这样做),然后在完成后返回主线程。编辑以显示在BackgroundWorker
上的尝试。请参见FrmMain()构造函数丢失了InitializeComponent()调用。是的,那会爆炸的。你能详细说明一下吗?我正在尝试合并一个进度条,只是为了显示几秒钟。问题是当表单加载时(称为加载报告),它不会关闭。就这样。此带有进度条的表单不需要在应用程序启动时加载,而是在用户单击特定报告时加载。报告需要运行,并且在数据库执行过程中,需要显示进度条。谢谢@Veena这个答案是针对应用程序加载的。通过谷歌“C#进度对话框”获取满足您需求的一些好信息,例如:
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
public FrmMain()
{
InitializeComponent();
backgroundWorker1.RunWorkerAsync();
var loading = new FrmLoading();
loading.ShowDialog();
}
private void BackgroundWorker1DoWork(object sender, DoWorkEventArgs e)
{
DbQuery();
}
private void BackgroundWorker1RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Loading.Close();
}