PointToScreen在布局期间返回变量结果

时间:2013-11-13 17:57:27

标签: c# winforms

修改

到目前为止,所有的答案都指出了最初编写的代码是hacky。我没有写它,也不完全理解它是如何工作的。 然而,在一般情况下,它确实有效。我尝试了各种整理,但由于PointToScreen的奇怪行为,它们无法解决基本问题。

解释这种行为的替代方法,我可以看到很难解释,如果不理解其他形式的内部工作(我现在不是),就是想出一种替代方法来实现所需的功能,按下按钮时出现在按钮顶部的小对话框。当前实现是一个显示在顶部的表单,然后跟踪原始表单以保持其位置。有更清洁的选择吗?

原始问题:

我正在尝试使用PointToScreen在表单(表单C)上将表单(表单A)放在控件(按钮B)的顶部:

Point buttonCorner = buttonB.Parent.PointToScreen(buttonB.Location);

其中buttonB是表单上FlowLayoutPanel的按钮。

大部分时间它都有效,我得到了我期望的位置。我在表单上的LocationChanged事件中使用此代码,以便表单A跟踪按钮B.这样工作正常。

然而,当另一个动作导致父窗体调整大小时,我发现buttonCorner的位置是偏移的,这样窗体A最终会离开屏幕(右边)。在此次活动之前,我的表格中没有任何部分出现在屏幕之外。

我能提出的唯一理论是LocationChanged事件在FlowLayoutPanel重新安排时触发,并且在此期间它返回不良位置。这看起来有点牵强,但我没有更好的理论。

2 个答案:

答案 0 :(得分:1)

假设您有panelApanelB。您必须注册LocationChanged而不是表单的panelB

panelB.LocationChanged += (s,e) => {
  Point buttonCorner = PanelControlFlow.PointToScreen(PanelControlFlow.Location);
  //...
};

无论如何,我觉得你的代码有错误的方法,你的2个控件可能不需要相互跟踪,除非你在运行时更改它们的位置。您应该提供更多详细信息,以便我们找到另一种更好的方法。请注意,FlowLayoutPanel会自动压缩控件并对其进行定位控件不会产生任何影响。

<强>更新: 为什么你的PointToScreen会返回一些屏幕外点。我已经对此进行了测试,当表单最小化时,其Location-32000, -32000。所有PointToScreen都将添加此Location,这意味着如果您的控件在您的表单上计算Left300,则其Left计算在-32000 + 300 = -31700上屏幕大约为TopLocationChanged也是如此。这就是为什么你的控制位置离开屏幕的原因。因此,您必须将要跟踪的控件的Location注册到表单中。为什么最小化窗口的-32000,-32000为{{1}}?我认为这是一个窗口隐藏在屏幕上的方式。

答案 1 :(得分:1)

 Point buttonCorner = PanelControlFlow.PointToScreen(PanelControlFlow.Location);

该代码肯定是错误的,Location值是相对于控件的Parent。如果您想知道面板左上角的位置,那么您必须使用:

 Point panelCorner = PanelControlFlow.PointToScreen(Point.Empty);

或面板中的按钮:

 Point buttonCorner = someButtonInPanel.Parent.PointToScreen(someButtonInPanel.Location);

然后在顶部获得另一个按钮:

 anotherButton.Location = anotherButton.Parent.PointToClient(buttonCorner);