我跌倒了一个深深的兔子洞。实际上我已经处理过两个问题。我认为没有人会有第一个问题的解决方案(在下一段中提到),所以我想真正的问题是如何可靠地使用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怪异,但我无法解决。
答案 0 :(得分:1)
我不完全理解为什么会这样,但这会产生正确的坐标:
var mainPosition = this.PointToClient(screenPosition);
mainPosition = new Point(
mainPosition.X + SystemInformation.VerticalResizeBorderThickness,
mainPosition.Y + SystemInformation.CaptionHeight + SystemInformation.HorizontalResizeBorderThickness);