0

编辑:

到目前为止,所有答案都指出最初编写的代码是 hacky。我没有写它,也不完全理解它是如何工作的。 但是,在一般情况下,它确实有效。我尝试了各种整理,但由于PointToScreen.

解释这种行为的另一种方法是想出一种替代方法来实现所需的功能,这是按下按钮时出现在按钮顶部的一个小对话框。当前的实现是出现在顶部的表单,然后跟踪原始表单以保持其位置。有更清洁的选择吗?

原始问题:

我正在尝试使用以下命令将表单(表单 A)放置在表单(表单 C)上的控件(按钮 B)之上PointToScreen

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

buttonB表单中的按钮在哪里FlowLayoutPanel

大多数情况下,我得到了我期望的位置。我在表单上的一个事件中使用此代码LocationChanged,以便表单 A 跟踪按钮 B。这工作正常。

但是,当另一个动作导致父表单调整大小时,我发现 的位置buttonCorner是偏移的,因此表单 A 最终离开屏幕(向右)。在此事件之前,我的表格中没有任何部分出现在屏幕上。

我能想到的唯一理论是事件在重新安排时LocationChanged触发 ,并且在此期间它返回一个错误的位置。FlowLayoutPanel这似乎有点牵强,但我没有更好的理论。

4

2 回答 2

1

假设你有panelApanelB。您必须注册以下形式LocationChangedpanelB非:

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

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

更新:出于您PointToScreen返回一些屏幕外点的原因。我已经对此进行了测试,当表单最小化时,它Location-32000, -32000. 所有的PointToScreen都会加上这个Location,也就是说如果你的控件已经Left在你的表单上进行了计算300,那么它Left在屏幕上的计算将是近似的-32000 + 300 = -31700。对于Top. 这就是您的控件的位置离开屏幕的原因。所以你必须注册LocationChanged你想要跟踪的控件而不是表单。为什么最小化的窗口Location-32000,-32000? 我认为这就是从屏幕上隐藏 Window 的方式。

于 2013-11-13T21:35:59.250 回答
1
 Point buttonCorner = PanelControlFlow.PointToScreen(PanelControlFlow.Location);

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

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

或面板中的按钮:

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

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

 anotherButton.Location = anotherButton.Parent.PointToClient(buttonCorner);
于 2013-11-13T23:05:00.200 回答