我知道可以通过操纵Control.Top
和来对齐控件的底部Control.Height
。同样Control.Right
。但是为什么.NET 决定不让这些属性直接被修改呢?自从最近几次我一直在处理控制定位以来,这令人沮丧。
6 回答
简短的回答:
我相信他们已经制作Bottom
和Right
只读了,不是因为它在技术上是必要的,而是作为一种记录方式,当/或/被修改时,这些属性会被重新计算。Top
Height
Left
Width
更长的答案:
有两种属性集:一种用于绝对坐标 ( Top
, Bottom
, Left
, Right
),另一种用于维度 ( Height
, Width
)。它们之间的关系通过以下两个不变量来定义:
Width == Right - Left
Height == Bottom - Top
现在,例如,如果 Microsoft 决定该Top
属性应该是可写的,他们需要做出进一步的设计决策:是否会改变Top
...
- 影响
Height
和保存Bottom
,或 - 保存
Height
和影响Bottom
?
除非他们引入某种允许用户选择的进一步“锚”属性,否则 Microsoft必须决定其中一个结果以保证上述不变式 (2)。
显然,他们选择了两种选择中的后者。接下来,微软需要记录他们的决定。他们可以Top
在他们的 MSDN 参考页面上提到调整的后果......事实证明他们就是这样做的:
对
Height
和Top
属性值所做的更改会导致Bottom
控件的属性值发生更改。—属性的 MSDN 参考页面的备注部分Control.Top
...或者他们可以将该Bottom
属性声明为只读,向我们的程序员建议该属性取决于其他两个(Top
和Height
)...他们也这样做了:
该
Bottom
属性是只读属性。Top
您可以通过更改或属性的值来操作此属性值Height
[...] —该属性的 MSDN 参考页面的备注部分Control.Bottom
所以他们用英语和另外的代码记录了他们的(任意)设计决定。
引用 Eric Lippert 的话:“你一直在问‘为什么? [功能]显然应该如何设计的概念;为什么不是这样?” “
“为什么不呢?”的答案 问题可能在:
- 这个“功能”(可设置的底部和右侧属性)没有被提议/被认为没有用
- 可设置的 Right 和 Bottom 的行为是模棱两可的 - 我是重新调整相关控件的大小(更改高度/宽度)还是重新定位(更改顶部/右侧)。对于这里的“正确”行为,不同的人会有不同的看法。
由于Bottom
和Right
是计算出来的,因此操作例如 Bottom like
Bottom = 100
将转换为(Top + Height) = 100
. 那个动作会模棱两可,你是想改变控件的高度还是要重新定位它?
因为坐标系是基于左上角的。(0,0) 是屏幕的左上角,所有基于位置的测量都相对于 (0,0)。在设置左上角坐标时,你的意思很清楚:位置。然而,右下角坐标更加模糊,因为它们还涉及高度和宽度(如前所述)。
如果将 5 添加到 Right 属性会发生什么?位置会改变,还是宽度会改变?这不是一个有用或有意义的功能。
编辑:
如果 left 和 top 不涉及调整大小,那么为什么要 bottom 和 right 呢?
因为坐标系基于左上角,而不是右下角。GDI,或您用来绘制控件的任何系统,根据通用原点 (0,0) 和控件上相对于该原点的一点来计算位置。因为通用原点是屏幕的左上角,所以使用控件的左上角作为定位点是最有意义的。
想象一下这两种情况:
场景 1 - 控件不计算右下角坐标,它实际上存储了这些坐标。GDI 已准备好绘制控件。左上角坐标设置为 (10,10),高度为 10,宽度为 10,右下角坐标为 (25,25)。控件应该怎么画?
场景 2 - 不是计算右下角坐标,而是计算高度和宽度。左上角设置为 (20,20),右下角设置为 (10,10)。控件应该怎么画?
通过将程序员限制在左上角和高度/宽度,上述情况将永远不会发生,从而节省处理时间和意外错误。
因为Right
是由 决定的Left+Width
,Bottom
是由 决定的Top+Height
。
您可以使用Left
、Top
、Width
和Height
来同样有效地定位控件。
这些属性理论上可以设置,但我猜他们认为这样做可能会导致太多问题。
因为底层架构不支持Right
和Bottom
,所以只让它们计算属性可能太方便了。
好吧,我承认,我猜。我看不出有什么明确的理由。您可能需要就此与 .NET 开发团队联系。
如果要更改 a 的大小或位置Control
,可以更改Control.Location和Control.Size属性。我相信Control.Bottom
andControl.Right
属性是从这些其他属性中计算出来的。