表单加载时的 C# WaitCursor
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1822620/
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
C# WaitCursor while form loads
提问by Alexandre Bell
I'm having a form that takes a few seconds to finally display. This form is called through:
我有一个需要几秒钟才能最终显示的表单。此表单通过以下方式调用:
using (ResultsForm frm = new ResultsForm())
{
this.Visible = false;
frm.ShowDialog();
this.Visible = true;
}
It's useful that I get the default cursor to Cursors.WaitCursor
while waiting for the form to finally display. Currently I can only seem to be able to do this successfully by using the static 'Current' property:
Cursors.WaitCursor
在等待表单最终显示时获得默认光标很有用。目前,我似乎只能通过使用静态“当前”属性成功地做到这一点:
using (ResultsForm frm = new ResultsForm())
{
//this.Visible = false;
Cursor.Current = Cursors.WaitCursor;
frm.ShowDialog();
//this.Visible = true;
}
But this has two problems:
但这有两个问题:
- It forces me to disable the MainForm hiding feature which I would like to retain.
- It increases coupling since
Cursor.Current = Cursor.Default;
needs to be called within the ResultsForm Shown event.
- 它迫使我禁用我想保留的 MainForm 隐藏功能。
- 它增加了耦合,因为
Cursor.Current = Cursor.Default;
需要在 ResultsForm Shown 事件中调用。
How can I change the Cursor while the form loads without changing the first code snippet and while avoiding coupling?
如何在表单加载时更改 Cursor 而不更改第一个代码片段并避免耦合?
UPDATE:Now the question was answered, video presentation was removed so I don't go over my ISP bandwidth limitations.
更新:现在问题得到了回答,视频演示被删除,所以我不会超过我的 ISP 带宽限制。
采纳答案by Glenn
Why do you have to remove the this.Visible = false? You should still be able to do it while setting the cursor.
为什么要删除 this.Visible = false?您应该仍然可以在设置光标时执行此操作。
Would it be an acceptable solution to have the ResultsForm set the cursor instead of the parent form? Get it to set the cursor before it starts the code that takes all the time, then set it back at the end.
让 ResultsForm 设置光标而不是父表单是一个可以接受的解决方案吗?让它在启动需要所有时间的代码之前设置光标,然后在最后设置它。
回答by Reed Copsey
It forces me to disable the MainForm hiding feature which I would like to retain.
它迫使我禁用我想保留的 MainForm 隐藏功能。
You should be able to do both, without issues.
您应该能够做到这两点,而不会出现问题。
It increases coupling since Cursor.Current = Cursor.Default; needs to be called within the ResultsForm Shown event
它增加了耦合,因为 Cursor.Current = Cursor.Default; 需要在 ResultsForm Shown 事件中调用
Have you tried putting your cursor logic entirely into the ResultsForm dialog code? You should be able to set Cursor.Current = Cursors.WaitCursor;
inside of the ResultsForm's constructor, and then have Cursor.Current = Cursor.Default;
set inside of the Shown
event.
您是否尝试将光标逻辑完全放入 ResultsForm 对话框代码中?您应该能够Cursor.Current = Cursors.WaitCursor;
在 ResultsForm 的构造函数内部进行设置,然后Cursor.Current = Cursor.Default;
在Shown
事件内部进行设置。
This would keep the logic entirely in the dialog, and out of the main window. You could also then keep the visibility toggling in the main window.
这会将逻辑完全保留在对话框中,而不是在主窗口之外。然后,您还可以在主窗口中保持可见性切换。
回答by Pavel Minaev
If you always want to display a wait cursor when loading this form (regardless of whether it's shown from), then, as Reed suggests, you should just do it in the form itself.
如果你总是想在加载这个表单时显示一个等待光标(不管它是否显示),那么,正如 Reed 建议的那样,你应该只在表单本身中进行。
However, if you only need the cursor in this one particular case of displaying a form, then you can use a lambda (or anonymous delegate, if you're dealing with C# 2.0) for an event handler:
但是,如果您只需要在显示表单的这种特殊情况下使用光标,那么您可以使用 lambda(或匿名委托,如果您使用的是 C# 2.0)作为事件处理程序:
using (ResultsForm frm = new ResultsForm())
{
this.Visible = false;
var oldCursor = Cursor.Current;
Action<object, EventArgs> restoreCursor =
delegate
{
Cursor.Current = oldCursor;
frm.Shown -= restoreCursor;
};
frm.Shown += restoreCursor;
Cursor.Current = Cursor.WaitCursor
frm.ShowDialog();
}
回答by SwDevMan81
You could make the main form the owner of the second form and make it modal:
您可以使主窗体成为第二个窗体的所有者并使其成为模态:
frm.ShowDialog(this);
Then in frm, add "Cursor.Current = Cursors.WaitCursor;" in the Constructor and add "Cursor.Current = Cursor.Default;" in the Shownevent.
然后在frm中,添加“Cursor.Current = Cursors.WaitCursor;” 在构造函数中添加“Cursor.Current = Cursor.Default;” 在Shown事件中。
I've tried this with a button and it works. The wait cursor shows and then turns back to default once the form loads:
我用一个按钮试过这个,它有效。等待光标显示,然后在表单加载后恢复为默认值:
Form1:
表格1:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WaitCursorTwoForms
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void ButtonClick(object sender, EventArgs e)
{
using(Form2 form2 = new Form2())
{
form2.ShowDialog(this);
}
}
}
}
Form2:
表格2:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace WaitCursorTwoForms
{
public partial class Form2 : Form
{
public Form2()
{
Cursor.Current = Cursors.WaitCursor;
InitializeComponent();
for (int i = 0; i < 10; i++)
{
Thread.Sleep(1000);
}
}
private void OnShown(object sender, EventArgs e)
{
Cursor.Current = Cursors.Default;
}
}
}
回答by Hans Passant
The cursor will change to WaitCursor but that will survive only a fraction of a second. The problem is that hiding your main form makes the cursor overlap the window that's behind your main form. Or the desktop. The revealed window gets a WM_SETCURSOR message from Windows and it will change the cursor to its preferred shape.
光标将更改为 WaitCursor,但它只会存活几分之一秒。问题是隐藏主窗体会使光标与主窗体后面的窗口重叠。或者桌面。显示的窗口从 Windows 获取 WM_SETCURSOR 消息,并将光标更改为其首选形状。
But there's a bigger problem with your approach. After the dialog closes, there's a fraction of a second where no window in your app is visible. Windows is forced to find another window to give the focus to, it won't be a window in your app. When your main form again becomes visible, it may well end up behind the window that got the focus. This behavior tends to be a bit flaky, you might not yet have found it.
但是你的方法有一个更大的问题。对话框关闭后,有几分之一秒,您的应用程序中没有窗口可见。Windows 被迫寻找另一个窗口来获得焦点,它不会是您的应用程序中的窗口。当您的主窗体再次可见时,它很可能最终位于获得焦点的窗口后面。这种行为往往有点不稳定,您可能还没有发现。
You can solve both problems by hiding the window a different way:
您可以通过以不同方式隐藏窗口来解决这两个问题:
this.Opacity = 0.01;