在上下文菜单中单击移动时,将鼠标位置设置为无边框 window 中的标题中心
Set mouse position to center of title in borderless window when clicking move in context menu
我正在寻找以下问题的解决方案:为了美观,我使用了无边框 window,因此我为此 window 创建了一个标题区域(它是 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_Click
中用 rootGrid.Focus();
和 rootGrid.CaptureMouse();
尝试过,但两者都没有将我的光标设置到 rootGrid
。
我为什么要这样做?在许多其他应用程序中,当我单击“移动”上下文菜单项时,鼠标会移动到标题的中心 window。
我在这里从我的代码中删除了不必要的事件处理程序。
首先,您需要一些互操作代码来获取和设置当前鼠标在屏幕上的位置。看看这些相关问题作为参考:Get mouse position. Set mouse position.
[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;
}
当然,您必须处理拖动 window 并稍后重置光标。
我正在寻找以下问题的解决方案:为了美观,我使用了无边框 window,因此我为此 window 创建了一个标题区域(它是 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_Click
中用 rootGrid.Focus();
和 rootGrid.CaptureMouse();
尝试过,但两者都没有将我的光标设置到 rootGrid
。
我为什么要这样做?在许多其他应用程序中,当我单击“移动”上下文菜单项时,鼠标会移动到标题的中心 window。
我在这里从我的代码中删除了不必要的事件处理程序。
首先,您需要一些互操作代码来获取和设置当前鼠标在屏幕上的位置。看看这些相关问题作为参考:Get mouse position. Set mouse position.
[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;
}
当然,您必须处理拖动 window 并稍后重置光标。