在WPF应用程序启动期间如何显示等待光标?

31

这是我希望在WPF应用程序启动时发生的基本事件。 这非常类似于Word在我的计算机上的启动方式。

  1. 显示忙碌光标。
  2. 执行基本初始化。 这需要几秒钟时间,并且需要在显示启动画面之前完成。
  3. 显示启动画面。 此启动画面显示更深入的初始化进度,并可能需要一段时间(从数据库缓存信息)。
  4. 显示默认光标。 由于启动画面正在显示进度,因此无需显示繁忙光标。
  5. 启动画面进度条完成后,显示主窗口。
  6. 关闭启动画面。

除了在启动画面显示之前显示繁忙光标之外,一切正常。 当我通过快捷方式执行应用程序时,等待光标会闪烁,但很快就会回到默认状态。 我尝试了不同的设置光标的方法,但没有一个有效,我认为问题在于我不在控件/窗口中--我是在App.xaml.cs中进行操作的。 而且,我设置的属性似乎是Windows Forms属性。 下面是我的代码摘录:

protected override void OnStartup(StartupEventArgs e)
{
  base.OnStartup(e);

  System.Windows.Forms.Application.UseWaitCursor = true;
  //System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor;
  //System.Windows.Forms.Application.DoEvents();

  Initialize();

  SplashWindow splash = new SplashWindow();
  splash.Show();

  System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default;

  // Right now I'm showing main window right after splash screen but I will eventually wait until splash screen closes.
  MainWindow main = new MainWindow();
  main.Show();
}
5个回答

65

这应该可以工作

Mouse.OverrideCursor = System.Windows.Input.Cursors.Wait;

使用System.Windows.Input而不是System.Windows.Forms


1
我已经添加了那个,但它仍然像以前一样运作。如果我在最初设置OverrideCursor后不将其重置为null,则当我将光标放在窗口上时,等待光标会显示出来。但是,在应用程序最初启动时不会显示它。 - bsh152s
嗯,我已经玩了一会儿,似乎在实际窗口之外改变光标非常困难,甚至是不可能的(即使使用这段代码,当鼠标离开窗口时等待光标也会消失)。很抱歉我不能提供更多帮助。 - Kevin DiTraglia
这很好。仅设置this.Cursor值仅更改窗口的光标,如果您悬停在控件上,则会获得默认光标而不是等待光标。Mouse.OverrideCursor似乎为窗口及其中所有内容设置等待光标。 - Richard Moore

49

如果您有一个需要大量时间来完成的任务,并且它在非GUI线程上运行(这是个好主意),您可以使用以下代码来更改应用程序光标:

Application.Current.Dispatcher.Invoke(() =>
{
    Mouse.OverrideCursor = Cursors.Wait;
});

当繁忙的进程完成后,请使用以下内容:

Application.Current.Dispatcher.Invoke(() =>
{
    Mouse.OverrideCursor = null;
});

5
        Mouse.OverrideCursor = System.Windows.Input.Cursors.Wait;
        InitializeComponent();
        ...
        Mouse.OverrideCursor = null;

2

我假设您想让忙碌光标出现的部分是 Initialize(),是吗?

如果是这样,请尝试以下方法:

  1. 在 MainWindow.xaml 上的 <Window> 元素中,设置以下属性:Visibility="Hidden"Cursor="Wait"
  2. 在 MainWindow.xaml.cs 中,将初始化代码从构造函数中移出并放入一个名为 public Initialize() 的方法中,以便任何依赖于 Initialize() 调用的代码都不会被执行。确保 Initialize() 方法结束时将 Visiblity 属性设置为 Visible 并重置 Cursor
  3. 更新上面发布的代码片段,使其类似于以下内容:
protected override void OnStartup(StartupEventArgs e)
{
  base.OnStartup(e);

  MainWindow main = new MainWindow();
  main.Show(); // this should set the cursor how you want it
  Initialize();
  SplashWindow splash = new SplashWindow();
  splash.Show();
  main.Initialize(); // now invoke the Initialize method you created
  // Right now I'm showing main window right after splash screen but I will eventually wait until splash screen closes.
}

0

对我来说,使用上述方法的混合效果很好:

class MyForm : System.Windows.Window {}

class Test{
   MyForm myForm;

   void ShowWaitCurserInMyForm(){
      //before kicking off the stuff I'm waiting for: 
      System.Windows.Forms.Application.UseWaitCursor = true; // disables all Input from the mouse
      myForm.Cursor = System.Windows.Input.Cursors.Wait; // actually displays a wait Cursor

      // do time intensive stuff here, if we wait for an event, following stuff belongs in its handler

      System.Windows.Forms.Application.UseWaitCursor = false; // reenables all Input from the mouse
      myForm.Cursor = null; // reset the Cursor visually
   }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接