C# WPF 捕获键盘和鼠标

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22155512/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 11:06:13  来源:igfitidea点击:

C# WPF Capture Keyboard and Mouse

c#wpfmouseeventkeyboard-events

提问by Jimmy

So I have a WPF Window that captures mouse events on an image. I am doing this by the following code:

所以我有一个 WPF 窗口,可以捕获图像上的鼠标事件。我通过以下代码执行此操作:

<Image Name="imgPrimaryImage" Width="512" Height="512" RenderOptions.BitmapScalingMode="NearestNeighbor" Margin="5"
       Source="{Binding Path=ImageMgr.ImageSource}"
                 MouseLeftButtonDown="OnMouseLeftButtonDown" 
                 MouseMove="OnMouseMove"
                 MouseLeftButtonUp="OnMouseLeftButtonUp"/>

Application Functionality:While the user moves the mouse left and right it changes the size of the image so long as they have the left mouse button pressed.

应用程序功能:当用户左右移动鼠标时,只要按下鼠标左键,它就会改变图像的大小。

Question:Is is possible to also capture keyboard events while capturing the mouse move event.

问题:是否可以在捕获鼠标移动事件的同时捕获键盘事件。

End Result:I want to be able to change the mouse speed based on CTRL and SHIFT pressed. I have the code I need to change the mouse speed, I am just wondering how I can get it so that if the user is holding CTRL while they left click and drag on the image it changes the speed.

最终结果:我希望能够根据 CTRL 和 SHIFT 按下来更改鼠标速度。我有我需要更改鼠标速度的代码,我只是想知道如何获得它,以便如果用户在左键单击并拖动图像时按住 CTRL 键,它会改变速度。

If anyone has any insight on this (i.e. articles, literature, or advice) that would be excellent. Thank you and if there is any additional information needed please let me know.

如果有人对此有任何见解(即文章、文献或建议),那就太好了。谢谢,如果需要任何其他信息,请告诉我。

采纳答案by dkozl

To sum up comments if you want to check state of keyboard keys you can use Keyboardclass which provides IsKeyDownmethod

总结评论,如果你想检查键盘键的状态,你可以使用Keyboard提供IsKeyDown方法的类

var isShift = Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift);
var isCtrl = Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl);
var isAlt = Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt);

or use its Modifiersproperty

或使用其Modifiers财产

var isShift = Keyboard.Modifiers.HasFlag(ModifierKeys.Shift);
var isCtrl = Keyboard.Modifiers.HasFlag(ModifierKeys.Control);
var isAlt = Keyboard.Modifiers.HasFlag(ModifierKeys.Alt);

回答by BenVlodgi

Set booleanflags based on what keys are pressed in the key pressed event.

boolean根据按键事件中按下的按键设置标志。

In the OnMouseMoverecord the mouse position if null. Otherwise calculate the distance traveled, and amplify it or dampen it based on the speed up or slow down flags you've set already.

OnMouseMove记录鼠标位置如果为空。否则计算行驶的距离,并根据您已经设置的加速或减速标志放大或抑制它。

To dampen or amplify, once you have the X and Y change from the last point, multiply by 2, or divide by 2... (you can choose your own numbers), now add the new YX change to the current mouse XY coordinates and set the mouse position.

要抑制或放大,一旦您从最后一个点获得 X 和 Y 变化,乘以 2,或除以 2...(您可以选择自己的数字),现在将新的 YX 变化添加到当前鼠标 XY 坐标并设置鼠标位置。

Here is what the MouseMovewould look like, and some of the private variables needed. In my Example you have to have Formsincluded as a reference. I did not include Forms in my Include statements, because it mucks up IntelliSense in WPF applications. You will still need to maintain those _speedUpand _slowDownvariables with your KeyDownevents

下面是它的MouseMove样子,以及一些需要的私有变量。在我的示例中,您必须Forms包含作为参考。我没有在我的 Include 语句中包含 Forms,因为它在 WPF 应用程序中破坏了 IntelliSense。您仍然需要在事件中维护这些_speedUp_slowDown变量KeyDown

private bool entering = true;
private Point _previousPoint;
private bool _speedUp;
private bool _slowDown;
private double _speedMod = 2;
private double _slowMod = .5;

private void OnMouseMove(object sender, MouseEventArgs e)
{
    Point curr = new Point(System.Windows.Forms.Cursor.Position.X, System.Windows.Forms.Cursor.Position.Y);

    if (entering)
    {
        _previousPoint = curr;
        entering = false;
    }
    if (_previousPoint == curr)
        return; // The mouse hasn't really moved

    Vector delta = curr - _previousPoint;
    if (_slowDown && !_speedUp)
        delta *= _slowMod;
    else if (_speedUp && !_slowDown)
        delta *= _speedMod;
    else
    {
        _previousPoint = curr;
        return; //no modifiers... lets not do anything
    }
    Point newPoint = _previousPoint + delta;
    _previousPoint = newPoint;
    //Set the point
    System.Windows.Forms.Cursor.Position = new System.Drawing.Point((int)newPoint.X, (int)newPoint.Y);
}

EDIT:I put the key down events in my window definition, and it works just fine. Although as pointed out in the comments of this thread, using Keyboard.IsKeyDownis much simpler. I also edited the code above to not cause weird jumping issues

编辑:我把按键按下事件放在我的窗口定义中,它工作得很好。尽管正如该线程的评论中所指出的那样,使用Keyboard.IsKeyDown要简单得多。我还编辑了上面的代码,以免引起奇怪的跳跃问题

private void Window_KeyDown(object sender, KeyEventArgs e)
{
    _slowDown = true;
    if (e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl)
        _slowDown = true;
    else if (e.Key == Key.LeftShift || e.Key == Key.RightShift)
        _speedUp = true;
}

private void Window_KeyUp(object sender, KeyEventArgs e)
{
    if (e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl)
        _slowDown = false;
    else if (e.Key == Key.LeftShift || e.Key == Key.RightShift)
        _speedUp = false;
}

private void Window_MouseLeave(object sender, MouseEventArgs e)
{
    entering = true;
}