客户/屏幕坐标转换

时间:2014-02-05 22:44:37

标签: c# .net winforms coordinates

我跌倒了一个深深的兔子洞。实际上我已经处理过两个问题。我认为没有人会有第一个问题的解决方案(在下一段中提到),所以我想真正的问题是如何可靠地使用PointToScreen / PointToClient。

我想使用气球来显示我编写的用户控件的验证失败。这样做的方法是使用带有IsBalloon集的工具提示。在我的验证错误处理程序中,我使用我的user-control作为参数在工具提示上调用Show()。如果我单击另一个控件,这是有效的,但如果我使用tab离开控件则不行。我甚至试过像在另一个线程上排队任务睡觉一样的黑客,然后尝试显示气球。什么都行不通。

所以,我决定尝试绕过这个并使用主窗口(“this”)作为参数并指定坐标,即:

_balloon.Show(text, this, pos);  

但我似乎无法计算位置(pos)。

我希望这个位置是控件的右下角,所以这就是:

var clientBottomRight = new Point(_ctrlCallbackPhone.Width, _ctrlCallbackPhone.Height);  

然后,我试着像这样得到那个地方的实际屏幕坐标:

var screenPosition = _ctrlCallbackPhone.PointToScreen(clientBottomRight);  

最后,我尝试获取主窗体上的坐标(“this”),如下所示:

var mainPosition = this.PointToClient(screenPosition);  

然后我展示气球。由于Windows错误,你必须做两次。

_balloon.Show(string.Empty, this, mainPosition);  
_balloon.Show(text, this, mainPosition);  

结果远远高于它应该在的左侧和左侧。虽然错误的边缘看起来与标题栏的大小有关,但我不知道它是怎么回事。我正在获取一个点的屏幕坐标,并询问同一点的客户端坐标。

现在,当然,如果某人有一个真正的解决方案,当我离开控件时让气球工作,我就不再关心屏幕坐标了。我想这是某种Windows怪异,但我无法解决。

1 个答案:

答案 0 :(得分:1)

我不完全理解为什么会这样,但这会产生正确的坐标:

var mainPosition = this.PointToClient(screenPosition);
mainPosition = new Point(
               mainPosition.X + SystemInformation.VerticalResizeBorderThickness,
               mainPosition.Y + SystemInformation.CaptionHeight + SystemInformation.HorizontalResizeBorderThickness);