在带有滚动条的面板上获取光标位置

5
我已经建立了一个简单的程序(到目前为止),其中一个大的面板作为程序的“工作区”。我在其上绘制了网格,并实现了一些功能,例如将光标捕捉到最近的网格点等等。我在窗口底部拥有一个状态栏,用于显示我的当前位置。但是,无论我滚动到哪里(假设垂直滚动条相对于顶部距离为10%,水平滚动条为25%),它都会显示光标位置与实际窗口的位置关系。
我有一个OnMouseMove事件来处理这个问题:
private void WorkArea_MouseMove(object sender, MouseEventArgs e)
{
    GridCursor = grid.GetSnapToPosition(new Point(e.X, e.Y));
    toolStripStatusLabel1.Text = grid.GetSnapToPosition(new Point(e.X, e.Y)).ToString();
    Refresh();
}

这段代码可以根据光标定位,将其绘制到正确的位置等,运行效果与预期相符。 但是,如果我滚动屏幕,读数仍然是相同的。 即使我的竖直和水平滚动条滚动到一半,当我把光标放在左上角时,它也显示为0,0,而不是实际应该是5000,5000(针对一个10k x 10k的面板)。

如何确定面板在滚动条方面的绝对位置?


所以 WorkArea 是一个面板,对吗?GridCursorgridGetSnapToPosition 是什么?AutoScroll 打开了吗? - TaW
2个回答

4
你需要根据滚动位置来调整位置偏移量:
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
      Point scrolledPoint = new Point( e.X - panel1.AutoScrollPosition.X, 
                                       e.Y - panel1.AutoScrollPosition.Y);

      ..
}

请注意,AutoScrollPosition的值为负数。
如果控件已经滚动离开其起始位置(0,0),则检索到的X和Y坐标值是负数。当您设置此属性时,必须始终分配正的X和Y值以相对于起始位置设置滚动位置。例如,如果您有一个水平滚动条,并将x和y设置为200,则将滚动向右移动200个像素;如果您将x和y设置为100,则滚动看起来向左跳跃了100个像素,因为您将其设置为距离起始位置100个像素。在第一种情况下,AutoScrollPosition返回{-200,0};在第二种情况下,它返回{-100,0}。

如果你正在使用DataGridView,你要查找的属性是HorizontalScrollingOffset和VerticalScrollingOffset。 - zbz.lvlv

-1

WinForms:

方法Control.PointToClient允许您将鼠标位置转换为相对于控件本身的位置。

Point point = grid.PointToClient(new Point(e.X, e.Y))

WPF:

使用 Mouse.GetPosition 可以获取鼠标相对于特定控件的位置:

Point position = Mouse.GetPosition(grid);

从外观上看,这只适用于WPF。有没有办法在WinForms中实现这个?我看到了一些关于“Cursor.Current”的内容,但似乎找不到如何使用此对象的任何信息(只是尝试从中获取一个Point对象)。 - Zulukas
啊,错过了你的WinForms标签,添加了单独的解决方案。 - Chrille

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接