【问题标题】:How to get mouse position on screen in WPF?如何在 WPF 中获取鼠标在屏幕上的位置?
【发布时间】:2015-04-23 11:24:44
【问题描述】:

它适用于特定控件,但不适用于特定控件。

如何获取鼠标位置和使用鼠标事件,而不依赖于任何控件,直接从屏幕(没有平台调用)?

需要2分:

  1. 鼠标不在控件内,而是在屏幕上时的鼠标事件。
  2. 鼠标不在控件内,而是在屏幕上时的鼠标位置。

应该不用Platform Invoke来解决。

接下来的两个不起作用:

System.Windows.Input.Mouse.GetPosition(this)

不会将鼠标位置移出特定控件。

System.Windows.Forms.Cursor.Position.X

System.Windows.Forms.Cursor.Position 不起作用,因为它在 WPF 应用程序中没有类型,但它在 Windows 窗体应用程序中起作用。

IntelliSense 获取 System.Windows.Forms.Cursor.Position,但它没有获取任何类型的 Position,因此我无法获取:

Position.X    
Position.Y

Point pointToWindow = Mouse.GetPosition(this);

Point pointToScreen = PointToScreen(pointToWindow);

不会将鼠标位置移出特定控件。

【问题讨论】:

    标签: c# .net wpf c#-4.0 mouse-position


    【解决方案1】:

    使用控件的MouseDown 事件你可以试试这个:

    var point = e.GetPosition(this.YourControl);
    

    编辑: 您可以使用Mouse.Capture(YourControl); 将鼠标事件捕获到特定控件,因此即使它不在该控件上,它也会捕获鼠标事件。这是link

    【讨论】:

    • 您可以将它用于包含所有控件的主控件,例如UserControlWindow
    • 是的,但在我的情况下,当鼠标在窗口外时,我在窗口上绘图。当用户移动鼠标做其他事情时,我的目标是通过鼠标在背景窗口上绘制。如果不可能,请告诉我。
    • Mouse.Capture(YourControl) 有效。第二点解决了,很好,现在如何解决第一点?如何直接在屏幕上独立于控件使用鼠标事件?我可以使用无限线程来解决它,但是有没有像控件这样的现成方法?
    • @ZiyaCeferov 不确定是否可行!
    • "不确定是否可行!" - 好的,无论如何,主要问题都解决了。
    【解决方案2】:

    您可以使用PointToScreen

    转换代表当前坐标系的Point 可视化为屏幕坐标中的一个点。

    类似这样的:

    private void MouseCordinateMethod(object sender, MouseEventArgs e)
    {
        var relativePosition = e.GetPosition(this);
        var point= PointToScreen(relativePosition);
        _x.HorizontalOffset = point.X;
        _x.VerticalOffset = point.Y;
    }
    

    注意Mouse.GetPosition返回一个Point,PointToScreen将point转换为屏幕坐标

    编辑:

    您可以使用Mouse.Capture(SepcificControl);。来自MSDN

    捕获指定元素的鼠标输入。

    【讨论】:

    • 它不能解决特定的控件。我的应用程序没有窗口,它通过鼠标在背景上绘制,而用户使用鼠标做其他事情。它只是复制鼠标移动。如果没有平台调用是不可能的,请告诉我。这个问题没有回答。
    • @ZiyaCeferov:- 抱歉回复晚了,但是您可以使用 Mouse.Capture(SpecificControl); 来完成您的任务
    • 是的,很好用。解决了两个问题之一,另一个问题呢:如何在屏幕上直接使用没有特定控件的鼠标事件?我可以使用无限线程或计时器来解决它,但我问:有没有像我们使用控件那样的现成方法?
    • 鼠标钩子由 Platform Invoke 工作。 “不太确定” - 好的,我认为这是不可能的,我需要使用计时器或无限线程。无论如何,主要问题都解决了。
    【解决方案3】:

    我几乎没有新发现,

    代码如下,首先构建并运行窗口,

    然后只需在窗口上滚动一次鼠标即可调用鼠标位置的无限屏幕检测。

    (因此我在问题的第二点中没有找到检测鼠标事件失控的方法,但类似使用无限线程。)

    但我只是在WPF项目中使用了一点技巧来启用Windows.Forms,只需在纯方法中使用Forms代码,然后在事件代码块中引用该方法。

    .

    代码如下:

    添加两个对项目的引用:

    System.Drawing 
    System.Windows.Forms
    

    Xaml 部分:

    <Window x:Class="Test.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:g="clr-namespace:Gma.UserActivityMonitor;assembly=Gma.UserActivityMonitor"
            Title="MainWindow" Height="350" Width="525" 
            MouseWheel="MainWindow_OnMouseWheel">
        <Grid>
           <TextBlock Name="TBK" /> 
        </Grid>
    </Window>
    

    类代码:

    public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            public void KeepReportMousePos()
            {
                //Endless Report Mouse position
                Task.Factory.StartNew(() =>
                {
                    while(true){
                        this.Dispatcher.Invoke(
                            DispatcherPriority.SystemIdle,
                            new Action(() =>
                            {
                                GetCursorPos();
                            }));
                    }
                });
            }
            public void GetCursorPos()
            {
                //get the mouse position and show on the TextBlock
                System.Drawing.Point p = System.Windows.Forms.Cursor.Position;
                TBK.Text = p.X + " " + p.Y;
            }
    
            private void MainWindow_OnMouseWheel(object sender, MouseWheelEventArgs e)
            {
                //invoke mouse position detect when wheel the mouse
                KeepReportMousePos();
            }
        }
    

    【讨论】:

      【解决方案4】:

      为什么要把事情复杂化?只需传递null 即可获取屏幕坐标:

      private void MouseCordinateMethod(object sender, MouseEventArgs e)
      {
          var screenPos = e.GetPosition(null);
          // ...
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多