What is the best way to show a WPF window at the mouse location (to the top left of the mouse)?
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:
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? 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();