C# 如何在 Winforms 中为长加载表单显示“正在加载...请稍候”消息?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1918158/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I show a "Loading . . . please wait" message in Winforms for a long loading form?
提问by Sadegh
I have a form that is very slow because there are many controls placed on the form.
我有一个非常慢的表单,因为表单上放置了许多控件。
As a result the form takes a long time to loaded.
因此,表单需要很长时间才能加载。
How do I load the form first, then display it and while loading delay show another form which that have message like "Loading... please wait.?"
如何首先加载表单,然后显示它,并在加载延迟时显示另一个表单,其中包含“正在加载...请稍候。?”之类的消息。
采纳答案by Ash
Using a separate thread to display a simple please wait message is overkill especially if you don't have much experience with threading.
使用单独的线程来显示简单的请等待消息是多余的,特别是如果您没有太多线程经验。
A much simpler approach is to create a "Please wait" form and display it as a mode-less window just before the slow loading form. Once the main form has finished loading, hide the please wait form.
一个更简单的方法是创建一个“请稍候”表单并在缓慢加载表单之前将其显示为无模式窗口。主窗体加载完成后,隐藏请稍候窗体。
In this way you are using just the one main UI thread to firstly display the please wait form and then load your main form.
通过这种方式,您只需使用一个主 UI 线程来首先显示请等待表单,然后加载您的主表单。
The only limitation to this approach is that your please wait form cannot be animated (such as a animated GIF) because the thread is busy loading your main form.
这种方法的唯一限制是您的请等待表单不能动画(例如动画 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();
回答by David Basarab
回答by unholysampler
You should create a background thread to to create and populate the form. This will allow your foreground thread to show the loading message.
您应该创建一个后台线程来创建和填充表单。这将允许您的前台线程显示加载消息。
回答by Henk Holterman
A simple solution:
一个简单的解决方案:
using (Form2 f2 = new Form2())
{
f2.Show();
f2.Update();
System.Threading.Thread.Sleep(2500);
} // f2 is closed and disposed here
And then substitute your Loading for the Sleep.
This blocks the UI thread, on purpose.
然后用你的 Loading 代替 Sleep。
这会故意阻止 UI 线程。
回答by Grzenio
You can take a look at my splash screen implementation: C# winforms startup (Splash) form not hiding
你可以看看我的闪屏实现: C# winforms启动(Splash)表单不隐藏
回答by goku_da_master
I looked at most the solutions posted, but came across a different one that I prefer. It's simple, doesn't use threads, and works for what I want it to.
我查看了大多数发布的解决方案,但遇到了我更喜欢的不同解决方案。它很简单,不使用线程,并且可以满足我的要求。
http://weblogs.asp.net/kennykerr/archive/2004/11/26/where-is-form-s-loaded-event.aspx
http://weblogs.asp.net/kennykerr/archive/2004/11/26/where-is-form-s-loaded-event.aspx
I added to the solution in the article and moved the code into a base class that all my forms inherit from. Now I just call one function: ShowWaitForm() during the frm_load() event of any form that needs a wait dialogue box while the form is loading. Here's the code:
我添加到文章中的解决方案并将代码移动到我所有表单都继承的基类中。现在我只在窗体加载时需要等待对话框的任何窗体的 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 is the name of a form you create to look like a wait dialogue. I added a SetMessage() function to customize the text on the wait form.
MyWaitForm 是您创建的看起来像等待对话的表单的名称。我添加了一个 SetMessage() 函数来自定义等待表单上的文本。
回答by ahmadnaziF
Another way of making "Loading screen" only display at certain time is, put it before the event and dismiss it after event finished doing it's job.
使“加载屏幕”仅在特定时间显示的另一种方法是,将其放在事件之前,并在事件完成工作后关闭它。
For example: you want to display a loading form for an event of saving result as MS Excel file and dismiss it after finished processing, do as follows:
例如:要显示一个将结果保存为 MS Excel 文件的事件的加载表单并在处理完成后将其关闭,请执行以下操作:
LoadingWindow loadingWindow = new LoadingWindow();
try
{
loadingWindow.Show();
this.exportToExcelfile();
loadingWindow.Close();
}
catch (Exception ex)
{
MessageBox.Show("Exception EXPORT: " + ex.Message);
}
Or you can put loadingWindow.Close()
inside finally
block.
或者你可以把loadingWindow.Close()
里面的finally
块。
回答by Juan Carlos Girón
The best approach when you also have an animated image is this one:
当您还有动画图像时,最好的方法是:
1- You have to create a "WaitForm" that receives the method that it will executed in background. Like this one
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 - You can use the Waitform like this
2 - 您可以像这样使用 Waitform
private void btnShowWait_Click(object sender, EventArgs e)
{
new WaitForm(() => /*Simulate long task*/ Thread.Sleep(2000)).ShowDialog();
}
回答by Daniel Bonetti
I put some animated gif in a form called FormWait
and then I called it as:
我把一些动画 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();
回答by Muhammad Waqas Aziz
Well i do it some thing like this.
好吧,我做这样的事情。
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();
}