在我的Windows应用程序启动期间,我必须调用Web服务来检索要加载到我的应用程序的一些默认数据。在加载表单期间,我运行后台工作程序来检索此数据。我想显示等待光标,直到检索到这些数据。我该怎么做?
我已经尝试在调用后台工作程序之前设置等待光标。当我报告100的进度时,我将其设置回默认光标。等待光标出现但当我移动鼠标时它会消失。
环境:
修改: 我按照Jay Riggs建议的方式设置光标。它只有在我不移动鼠标时才有效。
*的 *更新: 我创建了一个单击按钮,执行以下操作:当我按下按钮并单击并移动鼠标时,无论我是否移动鼠标,都会显示等待光标。
void BtnClick()
{
Cursor = Cursors.WaitCursor;
Thread.Sleep(8000);
Cursor = Cursors.Default;
}
如果我执行以下操作:我看到等待光标,当我移动鼠标时,它会消失在表单内部。如果我移动到状态栏或菜单栏,则会出现等待光标。
Cursor = Cursors.WaitCursor;
if (!backgroundWorker.IsBusy)
{
backGroundWorker.RunWorkerAsync();
}
void backGroundWorkerDoWork(object sender, DoWorkEventArgs e)
{
Thread.Sleep(8000);
}
void backGroundWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Cursor = Cursors.Default;
}
如果我执行以下操作:等待光标出现,当我移动鼠标时,它仍然会出现但在文本字段中移动时有时会闪烁。虽然光标变为等待光标,但它不会阻止您点击任何内容。
if (!backgroundWorker.IsBusy)
{
backGroundWorker.RunWorkerAsync();
}
void backGroundWorkerDoWork(object sender, DoWorkEventArgs e)
{
UseWaitCursor = true;
Thread.Sleep(8000);
}
void backGroundWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
UseWaitCursor = false;
}
答案 0 :(得分:18)
UseWaitCursor
是否有效? (调用RunWorkerAsync()时设置为true,调用完成事件时设置为false)。你现在用什么来设置光标?
答案 1 :(得分:11)
不要为此显示等待光标 - 而是使用表单上的控件来指示后台工作人员正忙着做某事。等待光标是UI线程使用的适当指示器(因为它表示用户不能/不应该触摸任何东西),但它不适合在后台发生的事情。
答案 2 :(得分:6)
在WPF中,我通过在启动Backgroundworker之前将Mouse.OverrideCursor
属性设置为Cursors.Wait
,然后在null
事件中将其重置为RunWorkerCompleted
来完成此操作。到目前为止似乎工作得很好。
public void go()
{
BackgroundWorker thread = new BackgroundWorker();
thread.DoWork += run;
thread.RunWorkerCompleted += taskCompleted;
thread.WorkerReportsProgress = true;
// Change mouse cursor to busy
Mouse.OverrideCursor = Cursors.Wait;
thread.RunWorkerAsync();
}
private void taskCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// Reset mouse cursor
Mouse.OverrideCursor = null;
}
答案 3 :(得分:4)
你应该使用BGW的RunWorkerCompleted event将光标设置回默认值。
修改强>
将光标设置为等待,然后在启动BGW之前调用此代码:
this.Cursor = Cursors.WaitCursor;
通过以下方式将光标重置在BGW的RunWorkerCompleted事件中:
this.Cursor = Cursors.Default;
答案 4 :(得分:1)
在MS论坛帖子UseWaitCursor not working but Cursor = Cursors.WaitCursor does../& Cursor.Current vs. this.Cursor
确认WF的UseWaitCursor实现错过了实际显示沙漏光标并显示HourGlass类的机会,可以与“使用”块一起使用
using (new HourGlass()) {
// Do something that takes time...
System.Threading.Thread.Sleep(2000);
}
答案 5 :(得分:0)
其他必须设置光标。下面的代码在计时器启动时设置等待光标,然后在计时器到期后将光标设置回前一个值。它按预期工作:等待光标在整个间隔内保持不变。当然,将光标移动到窗体外面会显示鼠标光标所在窗口的光标,但将其移回我的窗体会显示等待光标。
public partial class MyDialog : Form
{
private Timer myTimer;
public MyDialog()
{
InitializeComponent();
myTimer = new Timer();
myTimer.Tick += new EventHandler(myTimer_Tick);
myTimer.Interval = 5000;
myTimer.Enabled = false;
}
private Cursor SaveCursor;
private void button1_Click(object sender, EventArgs e)
{
Cursor = Cursors.WaitCursor;
myTimer.Enabled = true;
}
void myTimer_Tick(object sender, EventArgs e)
{
Cursor = SaveCursor;
myTimer.Enabled = false;
}
}
答案 6 :(得分:0)
Microsoft Reference Source为我们提供了Control.UseWaitCursor和Control.Cursor的实施。如果检查Control.Cursor,您将看到如果UseWaitCursor设置为True,则无论控件上设置了什么游标,Control.Cursor都会返回Cursor.WaitCursor。由于这种行为,Control.Cursor返回的值无法缓存。
// DON'T DO THIS: THIS CODE WILL BREAK IF UseWaitCursor IS SET TO TRUE
// Store the original cursor
Cursor cachedCursor = this.Cursor;
// Set the cursor to a wait cursor.
this.Cursor = Cursors.WaitCursor;
// Perform some task
// Restore the original cursor
this.Cursor = cachedCursor;
虽然上面看起来足够无害,但如果有人在执行之前将Control.UseWaitCursor设置为True,它会立即导致问题。其结果将是一个卡住的等待游标,因为Control.Cursor在上面的第一行返回了Cursors.WaitCursor。因此,更好的方法是更改光标:
// Change the cursor as needed
this.Cursor = Cursors.WaitCursor;
// Perform some task
// Restore the default cursor when finished.
this.Cursor = this.DefaultCursor;
对于绝大多数事情,上述内容应足以在需要时显示等待光标。但是,如果控件的子控件也修改了光标,则子控件设置的光标将覆盖在父控件上设置的光标。 IE如果在将光标设置为Cursors.WaitCursor的表单上将标签的光标设置为Cursors.IBeam,则标签将在窗体显示WaitCursor时显示IBeam。只有Control.Cursor返回与Control.DefaultCursor相同的值的控件才会在这种情况下显示表单上的WaitCursor集。这是Control.UseWaitCursor的用武之地。在表单上设置UseWaitCursor也会在其所有子项上设置UseWaitCursor。只要表单上没有任何控件使用上面的破解代码。 DataGridView只是使用上面断代码的众多控件之一。
但是..如果您不想要WaitCursor并想要保持控件用户在外部设置光标怎么办?在这种情况下,您的选项是有限的,您必须覆盖控件的Cursor属性以接收控件用户设置的游标,或者必须使用反射来访问基本Control类存储的内部游标值。然后,只有这样才能使用上面的第一个方法来缓存和恢复光标。 *注意:您必须缓存控件用户设置的内部游标值,而不是base.Cursor的结果!
答案 7 :(得分:0)
以下是我现在正在做的事情,希望能有所帮助。
private void LoadWaitCursor()
{
this.Dispatcher.Invoke((Action)(() =>
{
Mouse.OverrideCursor = Cursors.Wait;
}));
}
private void LoadDefaultCursor()
{
this.Dispatcher.Invoke((Action)(() =>
{
Mouse.OverrideCursor = null;
}));
}
答案 8 :(得分:0)
这里已经有很多答案,但我找到了另一个对我有用的解决方案,所以我想我会列出它。
private void ShowWaitCursor(){
Application.UseWaitCursor = true; //keeps waitcursor even when the thread ends.
System.Windows.Forms.Cursor.Current = Cursors.WaitCursor; //Normal mode of setting waitcursor
}
private void ShowNormalCursor(){
Application.UseWaitCursor = false;
System.Windows.Forms.Cursor.Current = Cursors.Default;
}
我像这样使用它们,并且接缝按照我期望的方式工作。特别是当我想在工人运行时显示等待光标时。希望这有助于其他人继续寻找。