C# 我如何显示“a”;加载。请稍等;长加载窗体的Winforms中的消息?
我有一个非常慢的表单,因为表单上放置了许多控件 因此,加载表单需要很长时间C# 我如何显示“a”;加载。请稍等;长加载窗体的Winforms中的消息?,c#,.net,winforms,.net-core,C#,.net,Winforms,.net Core,我有一个非常慢的表单,因为表单上放置了许多控件 因此,加载表单需要很长时间 如何首先加载表单,然后显示它,并在加载延迟时显示另一个表单,其中包含“正在加载…请稍候”之类的消息?“您想查看“启动”屏幕 显示另一个“Splash”表单并等待处理完成 下面是一个关于如何操作的示例。您应该创建一个后台线程来创建和填充表单。这将允许前台线程显示加载消息。一个简单的解决方案: using (Form2 f2 = new Form2()) { f2.Show(); f2.Update();
如何首先加载表单,然后显示它,并在加载延迟时显示另一个表单,其中包含“正在加载…请稍候”之类的消息?“您想查看“启动”屏幕 显示另一个“Splash”表单并等待处理完成
下面是一个关于如何操作的示例。您应该创建一个后台线程来创建和填充表单。这将允许前台线程显示加载消息。一个简单的解决方案:
using (Form2 f2 = new Form2())
{
f2.Show();
f2.Update();
System.Threading.Thread.Sleep(2500);
} // f2 is closed and disposed here
然后用负载代替睡眠。这会故意阻止UI线程 您可以查看我的启动屏幕实现:
使用单独的线程来显示简单的“请稍候”消息是过分的,尤其是在您没有太多线程经验的情况下 一种更简单的方法是创建一个“请等待”表单,并在缓慢加载表单之前将其显示为无模式窗口。主窗体加载完毕后,隐藏“请稍候”窗体 这样,您只需使用一个主UI线程,即可首先显示请等待表单,然后加载主表单 这种方法的唯一限制是,由于线程正忙于加载主窗体,因此无法为please wait窗体设置动画(如动画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();
我查看了大多数发布的解决方案,但发现了另一个我更喜欢的解决方案。它很简单,不使用线程,并为我想要的工作 我在文章中添加了解决方案,并将代码移动到一个基类中,我的所有表单都从该基类继承。现在,我只需调用一个函数:ShowWaitForm(),在任何窗体的frm_load()事件期间,该窗体在加载时需要等待对话框。代码如下:
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()函数来自定义等待表单上的文本。另一种使“加载屏幕”仅在特定时间显示的方法是,将其放在事件之前,并在事件完成其工作后将其关闭
例如:要将结果另存为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
块中。当您还有动画图像时,最好的方法是:
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();
}
我将一些动画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();
我是这样做的
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
//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);
NormalWaitDialog/*您的等待表单*/\u frmWaitDialog=null;
//Btn加载点击事件
_frmWaitDialog=新建NormalWaitDialog();
_frmWaitDialog.Showed+=async(s,ee)=>
{
等待任务。运行(()=>
{
//在这里做你的事
//制作长时间运行的循环以模拟长时间的过程
int x=0;
对于(int i=0;i
或者,如果您不想要动画等花哨的东西,您可以创建一个标签并将其固定到表单中,然后将其z索引从文档大纲窗口更改为0,并为其提供背景色,以便在运行Application.DoEvents()之后,其他控件不可见
在form load事件中执行一次,然后在form Showed事件中执行所有编码,并在显示事件的和处将label visible属性设置为false,然后再次运行Application.DoEvents()
。我知道已经很晚了,但我喜欢这个项目,我想与您分享,它非常有用,非常简单
exist在处理静态动画时使用动画图像的方法?@Sadegh,您需要在请等待表单上使用一个控件,该控件在内部创建一个线程来设置图像动画。我不认为标准的PictureBox能做到这一点。但是,如果您确实需要动画,那么David的一些链接页面值得一看代码>@C Sharper,你的评论一定被截断了,而且“不适当”一词从结尾就消失了。从没想过这样做,节省了我很多时间。工作完美无瑕。谢谢这几乎是行不通的。在加载窗口显示之前,前台线程将继续导出到其繁忙的外部文件。我尝试使用此方法,但遇到IO非法线程交叉异常。我修改了它,使它“线程安全”。这不是最佳实践,但对于简单的等待表单,它是可以接受的:将f.Close()替换为f.Invoke(newthreadstart(委托{f.Close();}));我在这里添加了一个经过测试的解决方案:它说mywaitform不存在。我发现这是一个最好的方法,我设计了自己的等待表单,它工作得很好。在等待表单打开时在屏幕上放置静态图像或文本是一个很好的主意。我将调用更改为ShowWaitForm,并将其放在基类中。然后,我在基类中添加了一个布尔属性,这样我就可以设置该属性,它将加载wait表单。真棒的解决方案!我尝试过类似的方法,但当我在Explorer中从链接文件类型打开应用程序时,它会使我的应用程序失去焦点…效果很好。谢谢+1我喜欢这个简单的解决方案。是的,它对动画GIF不起作用,但我刚刚在对话框上贴了一个沙漏的图像,我很乐意。嗨,大卫,链接给出了404