C# 如果鼠标光标因用户键入而被隐藏,则正确的方法是什么?

C# 如果鼠标光标因用户键入而被隐藏,则正确的方法是什么?,c#,wpf,mouse,C#,Wpf,Mouse,我在WPF应用程序中有一个控件,它包含一个文本框和一个提交按钮。submit按钮被设置为“default”,这样,当光标位于文本框中时,如果用户按下Enter键,按钮的单击处理程序将运行。单击处理程序启动的过程很长,因此我使用了如下编码的等待光标: public class WaitCursor: IDisposable { private readonly System.Windows.Input.Cursor _oldCursor = null; public WaitCu

我在WPF应用程序中有一个控件,它包含一个文本框和一个提交按钮。submit按钮被设置为“default”,这样,当光标位于文本框中时,如果用户按下Enter键,按钮的单击处理程序将运行。单击处理程序启动的过程很长,因此我使用了如下编码的等待光标:

public class WaitCursor: IDisposable
{
    private readonly System.Windows.Input.Cursor _oldCursor = null;

    public WaitCursor()
    {
        _oldCursor = System.Windows.Input.Mouse.OverrideCursor;
        System.Windows.Input.Mouse.OverrideCursor = System.Windows.Input.Cursors.Wait;
        // *** 1
    }

    ~WaitCursor()
        => Dispose(false);

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    public void Dispose(bool unused)
    {
        System.Windows.Input.Mouse.OverrideCursor = _oldCursor;
        // *** 2
    }
}
如果我在文本框中键入,鼠标光标将消失。这是我在许多应用程序中观察到的Windows上的标准行为。但是,如果我在文本框中键入,然后在不移动鼠标的情况下按Enter键,则在应用程序繁忙时不会显示鼠标光标,即使用户正在移动鼠标。实际上,只要鼠标光标在我的应用程序窗口上,它就会变得不可见,并一直保持这种状态,直到应用程序停止忙碌。这是不可取的

我尝试在上面代码中标记为
/***1
的位置添加
System.Windows.Forms.Cursor.Show()
。这解决了光标不显示的问题。但它引入了一个新问题,即当用户在应用程序中键入文本框时(在应用程序的生命周期内),光标不再自动隐藏。表示对Show()和Hide()方法的调用应该成对进行,因此我尝试在标有
/***2
的位置添加
System.Windows.Forms.Cursor.Hide()
。这修复了所有观察到的问题

但我不喜欢这种解决方案,原因有二:

  • 我正在使用System.Windows.Forms.Cursor和System.Windows.Input.Cursor提供的工具的组合。这感觉一定是不正确的
  • 当我实际上不想隐藏光标时,我不愿意指示应用程序“隐藏”光标,即使观察到的行为是,我只是撤销了先前调用Show()的效果。这似乎不是框架设计人员的意图(看起来他们真正想的是隐藏()光标,然后显示()),因此可能会意外中断
解决这个问题的正确方法是什么?如果有一种官方认可的方法可以做到这一点,那么我想这样做。

在开始流程之前移动(模拟从代码后面移动)鼠标怎么样

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        KeyDown += _OnKeyDown;
    }

    [DllImport("User32.dll")]
    private static extern bool SetCursorPos(int X, int Y);

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    internal static extern bool GetCursorPos(ref Win32Point pt);

    [StructLayout(LayoutKind.Sequential)]
    internal struct Win32Point
    {
        public Int32 X;
        public Int32 Y;
    };
    public static Point GetMousePosition()
    {
        Win32Point w32Mouse = new Win32Point();
        GetCursorPos(ref w32Mouse);
        return new Point(w32Mouse.X, w32Mouse.Y);
    }

    private void _OnKeyDown(object sender, KeyEventArgs keyEventArgs)
    {
        if (keyEventArgs.Key == Key.Enter)
        {
            Point pos = GetMousePosition();
            SetCursorPos((int)pos.X + 1, (int)pos.Y); //move 1 pixel
            SetCursorPos((int)pos.X - 1, (int)pos.Y); //move back to original position

            //start your process afterwards ..
        }
    }

例如,看看Windows登录,当它忙的时候,整个屏幕上都有一个进度环,可以清楚地看到正在发生的事情。这是我没有想到的方法。我想如果有人质疑,我会发现很难证明向项目中添加这种代码是合理的。我将尝试一下,看看它是否有效,尽管我在几天内无法恢复工作。我的解决方法是在
基类
AttachedBehavior
行为
中实现它。因此,您可以很容易地实现它。