我有一个非常慢的表单,因为表单上放置了许多控件.
因此,表单需要很长时间才能加载.
如何首先加载表单,然后显示它,并在加载延迟时显示另一个表单,其中包含"正在加载......请等待.?"的消息.
Ash*_*Ash 57
使用单独的线程来显示简单的请等待消息是过度的,特别是如果您没有太多的线程经验.
一种更简单的方法是创建一个"请等待"表单,并在缓慢加载表单之前将其显示为无模式窗口.主表单完成加载后,隐藏请等待表单.
通过这种方式,您只使用一个主UI线程首先显示请等待表单,然后加载主表单.
这种方法的唯一限制是您的请等待表单无法动画(例如动画GIF),因为线程正在忙于加载您的主表单.
PleaseWaitForm pleaseWait=new PleaseWaitForm ();
// Display form modelessly
pleaseWait.Show();
// ALlow main UI thread to properly display please wait form.
Application.DoEvents();
// Show or load the main form.
mainForm.ShowDialog();
Run Code Online (Sandbox Code Playgroud)
gok*_*ter 25
我最常查看了所发布的解决方案,但遇到了我更喜欢的另一个解决方案.它很简单,不使用线程,并且可以满足我的需求.
http://weblogs.asp.net/kennykerr/archive/2004/11/26/where-is-form-s-loaded-event.aspx
我在文章中添加了解决方案,并将代码移动到我的所有表单都继承自的基类中.现在我只是在表单加载时需要等待对话框的任何表单的frm_load()事件期间调用一个函数:ShowWaitForm().这是代码:
public class MyFormBase : System.Windows.Forms.Form
{
private MyWaitForm _waitForm;
protected void ShowWaitForm(string message)
{
// don't display more than one wait form at a time
if (_waitForm != null && !_waitForm.IsDisposed)
{
return;
}
_waitForm = new MyWaitForm();
_waitForm.SetMessage(message); // "Loading data. Please wait..."
_waitForm.TopMost = true;
_waitForm.StartPosition = FormStartPosition.CenterScreen;
_waitForm.Show();
_waitForm.Refresh();
// force the wait window to display for at least 700ms so it doesn't just flash on the screen
System.Threading.Thread.Sleep(700);
Application.Idle += OnLoaded;
}
private void OnLoaded(object sender, EventArgs e)
{
Application.Idle -= OnLoaded;
_waitForm.Close();
}
}
Run Code Online (Sandbox Code Playgroud)
MyWaitForm是您创建的表单的名称,看起来像等待对话.我添加了一个SetMessage()函数来自定义等待表单上的文本.
ahm*_*ziF 10
使"加载屏幕"仅在特定时间显示的另一种方式是,将其放在事件之前,并在事件完成之后将其解雇.
例如:您要为MS Excel文件显示保存结果的事件的加载表单,并在完成处理后将其关闭,请执行以下操作:
LoadingWindow loadingWindow = new LoadingWindow();
try
{
loadingWindow.Show();
this.exportToExcelfile();
loadingWindow.Close();
}
catch (Exception ex)
{
MessageBox.Show("Exception EXPORT: " + ex.Message);
}
Run Code Online (Sandbox Code Playgroud)
或者你可以放在loadingWindow.Close()内部finally.
简单的解决方案:
using (Form2 f2 = new Form2())
{
f2.Show();
f2.Update();
System.Threading.Thread.Sleep(2500);
} // f2 is closed and disposed here
Run Code Online (Sandbox Code Playgroud)
然后用你的装载代替睡眠.
这会故意阻止UI线程.
我将一些动画 gif 以名为的形式放入FormWait,然后将其命名为:
// show the form
new Thread(() => new FormWait().ShowDialog()).Start();
// do the heavy stuff here
// get the form reference back and close it
FormWait f = new FormWait();
f = (FormWait)Application.OpenForms["FormWait"];
f.Close();
Run Code Online (Sandbox Code Playgroud)
好吧,我做了这样的事情。
NormalWaitDialog/*your wait form*/ _frmWaitDialog = null;
//Btn Load Click Event
_frmWaitDialog = new NormalWaitDialog();
_frmWaitDialog.Shown += async (s, ee) =>
{
await Task.Run(() =>
{
// DO YOUR STUFF HERE
// And if you want to access the form controls you can do it like this
this.Invoke(new Action(() =>
{
//here you can access any control of form you want to access from cross thread! example
TextBox1.Text = "Any thing!";
}));
//Made long running loop to imitate lengthy process
int x = 0;
for (int i = 0; i < int.MaxValue; i++)
{
x += i;
}
}).ConfigureAwait(true);
_frmWaitDialog.Close();
};
_frmWaitDialog.ShowDialog(this);
Run Code Online (Sandbox Code Playgroud)