简体   繁体   English

在鼠标位置(鼠标左上角)显示WPF窗口的最佳方法是什么?

[英]What is the best way to show a WPF window at the mouse location (to the top left of the mouse)?

I have found that this works PART of the time by inheriting the Windows Forms mouse point and subtracting out the height and width of my window to set the left and top (since my window's size is fixed): 我发现这部分时间通过继承Windows窗体鼠标点并减去窗口的高度和宽度来设置左侧和顶部(因为我的窗口大小是固定的):

MyWindowObjectThatInheritsWindow window = new MyWindowObjectThatInheritsWindow();
System.Windows.Point mouseLocation = GetMousePositionWindowsForms();
window.Left = mouseLocation.X - 300;
window.Top = mouseLocation.Y - 240;
window.Show();

Edit: Here is the code for getting the mouse position... 编辑:这是获取鼠标位置的代码...

public System.Windows.Point GetMousePositionWindowsForms()
{
    System.Drawing.Point point = System.Windows.Forms.Control.MousePosition;
    return new System.Windows.Point(point.X, point.Y);
}

Note that this works by making the bottom right edge of the window touch the top left of your mouse cursor. 请注意,这可以通过使窗口的右下边缘触摸鼠标光标的左上角来实现。 But this breaks for different screen resolutions, or maybe multiple monitors with different resolutiosn? 但是这会打破不同的屏幕分辨率,或者可能有多个具有不同分辨率的显示器? I haven't fully narrowed it down yet, but I just tried this same code on another PC, and it seems to spawn the window not to the top left of the mouse cursor, but to the bottom left of it, and a good distance past it... 我还没有完全缩小它,但我只是尝试在另一台PC上使用相同的代码,它似乎产生的窗口不是鼠标光标的左上角,而是它的左下角,并且距离很远过去...

I should probably add that my window sizes to content, width and height, so I can't just use the ActualWidth and ActualHeight properties since they're not available. 我应该添加我的窗口大小到内容,宽度和高度,所以我不能只使用ActualWidth和ActualHeight属性,因为它们不可用。 Perhaps the issue is in getting that sizing right? 也许问题在于确保调整正确吗? Is there any way to do that? 有没有办法做到这一点? I know for sure the 300 and 240 is correct according to my main PC with two monitors running 1920x1080 resolutions, as I have calculated the widths and heights of all the objects in my window which I have explicitly sized. 我确定300和240是正确的根据我的主PC和两台显示器运行1920x1080分辨率,因为我已经计算了我已明确调整大小的窗口中所有对象的宽度和高度。 Edit: Just tried explicitly setting the height and width to 240/300, to ensure that the window is no longer sized to content, and I still have this issue when subtracting out the actual height and width! 编辑:只是尝试明确地将高度和宽度设置为240/300,以确保窗口不再符合内容大小,并且在减去实际高度和宽度时仍然存在这个问题!

Any ideas? 有任何想法吗?

In the end, this did the trick: 最后,这就是诀窍:

        protected override void OnContentRendered(EventArgs e)
        {
            base.OnContentRendered(e);
            MoveBottomRightEdgeOfWindowToMousePosition();
        }

        private void MoveBottomRightEdgeOfWindowToMousePosition()
        {
            var transform = PresentationSource.FromVisual(this).CompositionTarget.TransformFromDevice;
            var mouse = transform.Transform(GetMousePosition());
            Left = mouse.X - ActualWidth;
            Top = mouse.Y - ActualHeight;
        }

        public System.Windows.Point GetMousePosition()
        {
            System.Drawing.Point point = System.Windows.Forms.Control.MousePosition;
            return new System.Windows.Point(point.X, point.Y);
        }

Can you not use something like this?: 你不能用这样的东西吗?:

Point mousePositionInApp = Mouse.GetPosition(Application.Current.MainWindow);
Point mousePositionInScreenCoordinates = 
    Application.Current.MainWindow.PointToScreen(mousePositionInApp);

I haven't been able to test it, but I think it should work. 我无法测试它,但我认为它应该可行。


UPDATE >>> 更新>>>

You don't have to use the Application.Current.MainWindow as the parameter in these methods... it should still work if you have access to a Button or another UIElement in a handler: 您不必使用Application.Current.MainWindow作为这些方法的参数......如果你有机会到它应该仍然工作Button或其他UIElement的处理程序:

Point mousePositionInApp = Mouse.GetPosition(openButton);
Point mousePositionInScreenCoordinates = openButton.PointToScreen(mousePositionInApp);

Again, I haven't been able to test this, but if that fails as well, then you can find one more method in the How do I get the current mouse screen coordinates in WPF? 同样,我还没有能够测试这个,但如果失败了,那么你可以在如何获得WPF中的当前鼠标屏幕坐标中找到另外一种方法 post. 帖子。

You can also do this by slightly modifying your initial example and positioning the window before showing it. 您也可以通过稍微修改您的初始示例并在显示窗口之前定位窗口来执行此操作。

MyWindowObjectThatInheritsWindow window = new MyWindowObjectThatInheritsWindow();

var helper = new WindowInteropHelper(window);
var hwndSource = HwndSource.FromHwnd(helper.EnsureHandle());
var transformFromDevice = hwndSource.CompositionTarget.TransformFromDevice;

System.Windows.Point wpfMouseLocation = transformFromDevice.Transform(GetMousePositionWindowsForms());
window.Left = wpfMouseLocation.X - 300;
window.Top = wpfMouseLocation.Y - 240;
window.Show();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM