当前位置:  开发笔记 > 编程语言 > 正文

在WPF中更改光标有时会起作用,有时则不然

如何解决《在WPF中更改光标有时会起作用,有时则不然》经验,为你挑选了4个好方法。

在我的几个用户控件中,我使用了更改光标

this.Cursor = Cursors.Wait;

当我点击某些东西时.

现在我想在按钮点击的WPF页面上做同样的事情.当我将鼠标悬停在我的按钮上时,光标会变为一只手,但是当我单击它时,它不会更改为等待光标.我想知道这是否与它是一个按钮,或者因为这是一个页面而不是用户控件这一事实有关?这看似奇怪的行为.



1> Matt Hamilto..:

只有当光标位于特定页面/ usercontrol上时,您是否需要将光标作为"等待"光标?如果没有,我建议使用Mouse.OverrideCursor:

Mouse.OverrideCursor = Cursors.Wait;
try
{
    // do stuff
}
finally
{
    Mouse.OverrideCursor = null;
}

这会覆盖应用程序的光标而不仅仅是其UI的一部分,因此您描述的问题就会消失.



2> Dennis..:

我们在应用程序中执行此操作的一种方法是使用IDisposable然后使用using(){}块来确保光标在完成后重置.

public class OverrideCursor : IDisposable
{

  public OverrideCursor(Cursor changeToCursor)
  {
    Mouse.OverrideCursor = changeToCursor;
  }

  #region IDisposable Members

  public void Dispose()
  {
    Mouse.OverrideCursor = null;
  }

  #endregion
}

然后在你的代码中:

using (OverrideCursor cursor = new OverrideCursor(Cursors.Wait))
{
  // Do work...
}

覆盖将在以下任何一个结束时结束:到达using语句的结尾或; 如果抛出异常并且控制在语句结束之前离开语句块.

更新

为防止光标闪烁,您可以执行以下操作:

public class OverrideCursor : IDisposable
{
  static Stack s_Stack = new Stack();

  public OverrideCursor(Cursor changeToCursor)
  {
    s_Stack.Push(changeToCursor);

    if (Mouse.OverrideCursor != changeToCursor)
      Mouse.OverrideCursor = changeToCursor;
  }

  public void Dispose()
  {
    s_Stack.Pop();

    Cursor cursor = s_Stack.Count > 0 ? s_Stack.Peek() : null;

    if (cursor != Mouse.OverrideCursor)
      Mouse.OverrideCursor = cursor;
  }

}


使用部分的好解决方案.实际上我在一些项目中写的完全相同(没有堆栈,就是这样).你可以简化用法的一件事就是写:using(new OverrideCursor(Cursors.Wait)){// do stuff}而不是为它分配一个你可能不会使用的变量.

3> Zamboni..:

您可以在按钮上使用数据触发器(使用视图模型)来启用等待光标.


以下是视图模型中的代码:

public class MainViewModel : ViewModelBase
{
   // most code removed for this example

   public MainViewModel()
   {
      GoCommand = new DelegateCommand(OnGoCommand, CanGoCommand);
   }

   // flag used by data binding trigger
   private bool _isWorking = false;
   public bool IsWorking
   {
      get { return _isWorking; }
      set
      {
         _isWorking = value;
         OnPropertyChanged("IsWorking");
      }
   }

   // button click event gets processed here
   public ICommand GoCommand { get; private set; }
   private void OnGoCommand(object obj)
   {
      if ( _selectedCustomer != null )
      {
         // wait cursor ON
         IsWorking = true;
         _ds = OrdersManager.LoadToDataSet(_selectedCustomer.ID);
         OnPropertyChanged("GridData");

         // wait cursor off
         IsWorking = false;
      }
   }
}


请为您的投票添加评论,以帮助我理解原因.我多次使用此代码并获得了良好的效果.
我也没有得到downvote.当您使用MVvM(因此没有代码隐藏)并且想要控制特定控件的光标时,这个答案很有用.很有用.
我正在利用MVVM的优势,这是完美的答案.

4> Valeriu Cara..:

如果您的应用程序使用异步内容并且您正在摆弄鼠标光标,那么您可能只想在主UI线程中执行此操作.你可以使用app的Dispatcher线程:

Application.Current.Dispatcher.Invoke(() =>
{
    // The check is required to prevent cursor flickering
    if (Mouse.OverrideCursor != cursor)
        Mouse.OverrideCursor = cursor;
});

推荐阅读
coco2冰冰
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有