我有一个非常慢的表单,因为表单上放置了许多控件。
结果表单需要很长时间才能加载。
如何首先加载表单,然后显示它,并在加载延迟时显示另一个表单,其中包含“正在加载......请等待。”
答案 0 :(得分:53)
使用单独的线程来显示简单的请等待消息是过度的,特别是如果您没有太多的线程经验。
更简单的方法是创建一个“请等待”表单,并在缓慢加载表单之前将其显示为无模式窗口。主表单完成加载后,隐藏请等待表单。
通过这种方式,您只使用一个主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();
答案 1 :(得分:24)
我最常查看所发布的解决方案,但遇到了我更喜欢的另一个解决方案。它很简单,不使用线程,并且可以满足我的需求。
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();
}
}
MyWaitForm是您创建的表单的名称,看起来像是等待对话。我添加了一个SetMessage()函数来自定义等待表单上的文本。
答案 2 :(得分:18)
答案 3 :(得分:10)
另一种使“加载屏幕”仅在特定时间显示的方法是,在事件发生之前将其放置并在事件结束后将其解雇。
例如:您希望显示将结果保存为MS Excel文件的加载表单,并在完成处理后将其关闭,请执行以下操作:
LoadingWindow loadingWindow = new LoadingWindow();
try
{
loadingWindow.Show();
this.exportToExcelfile();
loadingWindow.Close();
}
catch (Exception ex)
{
MessageBox.Show("Exception EXPORT: " + ex.Message);
}
或者您可以将loadingWindow.Close()
放入finally
阻止。
答案 4 :(得分:7)
一个简单的解决方案:
using (Form2 f2 = new Form2())
{
f2.Show();
f2.Update();
System.Threading.Thread.Sleep(2500);
} // f2 is closed and disposed here
然后用你的装载代替睡眠 这会故意阻止UI线程。
答案 5 :(得分:5)
您应该创建一个后台线程来创建和填充表单。这将允许您的前台线程显示加载消息。
答案 6 :(得分:4)
您可以查看我的启动画面实现: C# winforms startup (Splash) form not hiding
答案 7 :(得分:3)
当您拥有动画图像时,最佳方法是:
1-你必须创建一个" WaitForm"接收它将在后台执行的方法。喜欢这个
public partial class WaitForm : Form
{
private readonly MethodInvoker method;
public WaitForm(MethodInvoker action)
{
InitializeComponent();
method = action;
}
private void WaitForm_Load(object sender, EventArgs e)
{
new Thread(() =>
{
method.Invoke();
InvokeAction(this, Dispose);
}).Start();
}
public static void InvokeAction(Control control, MethodInvoker action)
{
if (control.InvokeRequired)
{
control.BeginInvoke(action);
}
else
{
action();
}
}
}
2 - 您可以像这样使用Waitform
private void btnShowWait_Click(object sender, EventArgs e)
{
new WaitForm(() => /*Simulate long task*/ Thread.Sleep(2000)).ShowDialog();
}
答案 8 :(得分:3)
我将一些动画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();
答案 9 :(得分:3)
我做这样的事情。
NormalWaitDialog/*your wait form*/ _frmWaitDialog = null;
//For static wait dialog
//On an Event
_frmWaitDialog = new NormalWaitDialog();
_frmWaitDialog.Shown += async (s, e) =>
{
Refresh();
await Task.Run(() =>
{
//Do your stuff
});
_frmWaitDialog.Close();
};
_frmWaitDialog.ShowDialog(this);
//For animated wait dialog
//On an event
_frmWaitDialog = new NormalWaitDialog();
_frmWaitDialog.Shown += (s, e) =>
{
//create a async method and call the method here
LoadDataAsync();
};
_frmWaitDialog.ShowDialog(this);
//Async Method
private async void LoadDataAsync(){
await Task.Run(() =>
{
//Do your stuff
});
_frmWaitDialog.Close();
}
答案 10 :(得分:1)
或者,如果您不希望动画等任何花哨的东西,您可以创建一个标签并将其停靠形成表格,然后将其z-index从文档轮廓窗口更改为0并为其设置背景色,以便其他控件不可见而不是在表单加载事件中运行一次Application.DoEvents()
,并在表单显示事件中进行所有编码,并在和显示事件中将标签的visible属性设置为false,然后再次运行Application.DoEvents()
。
答案 11 :(得分:0)
我知道现在很晚,但是我喜欢这个项目,并想与您分享,它非常有用并且非常有用 Simple Display Dialog of Waiting in WinForms