1

我寻找以下问题的解决方案: 为了美观,我使用无边框窗口,因此我为该窗口创建了一个标题区域(它是Grid)。

  <Grid x:Name="rootGrid" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="{DynamicResource BackgroundColor}" >
    <Grid.ContextMenu>
        <ContextMenu>
            <MenuItem x:Name="cmiVerschieben" Header="Verschieben" Click="cmiVerschieben_Click"/>
        </ContextMenu>
    </Grid.ContextMenu>
    <!-- ... -->
</Grid>

现在我像大多数应用程序一样在标题栏中添加了一个上下文菜单(关闭、最大化、最小化、移动......)。

简单的命令不是问题,但是对于“移动”条目,我必须将鼠标光标从当前位置移动到标题网格的中心。

cmiVerschieben_ClickrootGrid.Focus();and尝试过rootGrid.CaptureMouse();,但两者都没有将光标设置为rootGrid.

我为什么要这样做?在许多其他应用程序中,当我单击“移动”上下文菜单项时,鼠标会移动到标题窗口的中心。

我在这里从我的代码中删除了不必要的事件处理程序。

4

1 回答 1

1

首先,您需要一些互操作代码来获取和设置当前鼠标在屏幕上的位置。看看这些相关问题作为参考:获取鼠标位置设置鼠标位置

[DllImport("User32.dll")]
private static extern bool SetCursorPos(int x, int y);

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool GetCursorPos(ref Win32Point pt);

[StructLayout(LayoutKind.Sequential)]
internal struct Win32Point
{
   public int X;
   public int Y;
}

private static Point GetMousePosition()
{
   Win32Point w32Mouse = new Win32Point();
   GetCursorPos(ref w32Mouse);

   return new Point(w32Mouse.X, w32Mouse.Y);
}

然后您可以计算与您的位置差异rootGrid并设置新的鼠标位置,以及不同的鼠标光标图标。

private void CmiVerschieben_OnClick(object sender, RoutedEventArgs e)
{
   var positionOnRootGrid = Mouse.GetPosition(rootGrid);
   var xDifference = (int)(positionOnRootGrid.X - rootGrid.ActualWidth / 2);
   var yDifference = (int)(positionOnRootGrid.Y - rootGrid.ActualHeight / 2);
   var absoluteMousePosition = GetMousePosition();

   var absoluteXPosition = absoluteMousePosition.X - xDifference;
   var absoluteYPosition = absoluteMousePosition.Y - yDifference;

   // Set the position in the center of the root grid
   SetCursorPos(absoluteXPosition, absoluteYPosition);

   // Set the mouse cursor icon for roorGrid
   rootGrid.Cursor = Cursors.SizeAll;
}

当然,您必须稍后处理拖动窗口并重置为光标。

于 2020-07-17T09:26:26.370 回答