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

C# 在鼠标位置(鼠标左上方)显示WPF窗口的最佳方式是什么?,c#,wpf,window,location,mouse,C#,Wpf,Window,Location,Mouse,我发现,这在一定程度上是有效的,方法是继承Windows窗体的鼠标点,减去窗口的高度和宽度以设置左侧和顶部(因为窗口的大小是固定的): 编辑:这是获取鼠标位置的代码 public System.Windows.Point GetMousePositionWindowsForms() { System.Drawing.Point point = System.Windows.Forms.Control.MousePosition; return new System.Windows

我发现,这在一定程度上是有效的,方法是继承Windows窗体的鼠标点,减去窗口的高度和宽度以设置左侧和顶部(因为窗口的大小是固定的):

编辑:这是获取鼠标位置的代码

public System.Windows.Point GetMousePositionWindowsForms()
{
    System.Drawing.Point point = System.Windows.Forms.Control.MousePosition;
    return new System.Windows.Point(point.X, point.Y);
}
请注意,这是通过使窗口的右下边缘接触鼠标光标的左上角来实现的。但这会因为不同的屏幕分辨率而中断,或者可能是因为多个显示器具有不同的分辨率n?我还没有完全缩小它的范围,但我只是在另一台电脑上尝试了同样的代码,它似乎不会在鼠标光标的左上角生成窗口,而是在它的左下角生成窗口,并且经过了一段很长的距离

我可能应该将窗口大小添加到内容、宽度和高度中,因此我不能只使用ActualWidth和ActualHeight属性,因为它们不可用。也许问题在于正确调整尺寸?有办法吗?我确信300和240是正确的,根据我的主PC,两台显示器的分辨率为1920x1080,因为我已经计算了我的窗口中所有对象的宽度和高度,我已经明确地调整了大小。编辑:只是尝试显式地将高度和宽度设置为240/300,以确保窗口不再按内容调整大小,而我在减去实际高度和宽度时仍然存在此问题


有什么想法吗?

你不能用这样的东西吗

Point mousePositionInApp = Mouse.GetPosition(Application.Current.MainWindow);
Point mousePositionInScreenCoordinates = 
    Application.Current.MainWindow.PointToScreen(mousePositionInApp);
我还没能测试它,但我认为它应该能工作


更新>>>

在这些方法中,您不必使用
Application.Current.MainWindow
作为参数。。。如果您有权访问处理程序中的
按钮
或另一个
ui元素
,则它仍然可以工作:

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

同样,我无法测试这一点,但如果同样失败,那么您可以在帖子中找到另一种方法。

最后,这成功了:

        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);
        }

您也可以通过稍微修改初始示例并在显示窗口之前定位窗口来实现这一点

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();

现在还不清楚您到底想要什么,甚至不清楚您的代码是做什么的(究竟返回GetMousePositionWindowsForms的是什么?)。你能说清楚一点吗?没问题。简而言之:我想将WPF窗口的右下边缘设置为鼠标光标的左上角。我已经在你要求的函数中添加了。问题或多或少是清楚的;但您的代码并不太多:它似乎是C#winforms和WPF的混合体。在任何情况下,我想你都可以和你的回答者继续讨论。@varocarbas是的,它使用WinForms在屏幕上获取鼠标点,但不幸的是,我得到的答案在我的情况下似乎不起作用,因为我的主窗口是隐藏的,因为我的应用程序只包含一个系统托盘图标。我不熟悉这种混合(通常,你可以直接在WPF中得到你想要的任何东西,或者创建一个winforms应用程序)。这是否会引发问题(错误地协调两个不同的框架)?在任何情况下,只需向Sheridan解释确切的情况,以便他能想出一个适合您的解决方案。我已经尝试过这个方法,但我从中得到了这个错误:PresentationCore.dll中发生了一个类型为“System.InvalidOperationException”的未经处理的异常。其他信息:此可视化未连接到PresentationSource.Ahhh,很抱歉在
MainWindow.xaml.cs
的构造函数中,尝试添加以下内容:
Application.Current.MainWindow=this。如果仍然不起作用,请尝试推迟对上述代码的调用。。。请参阅以了解更多信息。啊,实际上这不起作用,因为我的主窗口是隐藏的。我制作了一个WPF应用程序,它创建了一个任务栏图标并创建了一个隐藏窗口,所以我仍然看到这个错误。实际上,上面的代码来自MainWindow.cs,所以我只是尝试使用“this”对象,但不幸的是没有成功。这是主窗口XAML:我不确定我是否理解。。。那么,您在应用程序中使用了什么
窗口
?好问题。我不用窗户。我在系统托盘中创建一个系统托盘图标。当用户单击它时,事件处理程序将激发并为应用程序的用户界面(实际上不是MainWindow)创建一个窗口。运行良好。我有更好的运气将事情与“负载”事件挂钩;我发现如果使用OnContentTrendered,当对话框从其初始渲染位置移动时会出现闪烁效果
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();