有没有办法在WinForms中获取剪切控件的可见部分的大小?
一个非常简单的示例:在窗体上放置一个控件,使窗体宽度小于控件宽度。如何获得控件可见区域的宽度?在这种情况下,您可以使用表单的ClientSize,但并不总是那么简单。
一个更复杂(和实际)的例子:我有一个AutoSize设置为true的标签,它可以超出其包含控件的宽度,导致它被剪裁。当发生这种情况时,我需要知道。它并不像将标签的宽度与其容器的宽度进行比较那么简单,因为容器也可能具有AutoSize = true并且也会被剪裁。
目前我的方法是走向容器树,直到找到一个AutoSize = false的容器,然后获取它的宽度。我还必须考虑每个容器的填充。但是这只考虑控件被其容器或容器的容器等夹住。如果有问题的控件或任何容器被具有更高Z顺序的同级控件剪切,它将无法工作。我怀疑还有其他方法可以轻易打破这种做法。
将标签AutoSize更改为false不是一个选项。标签位于UserControl上,该控件设置为AutoSize,以便在标签增长时,UserControl随之增长。在不使用AutoSize的情况下使其工作非常痛苦。
我尝试使用的东西,但未成功:
Control.ClientSize
,Control.ClientRectangle
,Control.PreferredSize
,Control.CreateGraphics().VisibleClipBounds
。
我和Graphics课程玩过一点但是我在那里。 Graphics.VisibleClipBounds
听起来很有希望,但似乎总是与上面提到的其他尺寸属性一样。
这特别适用于WinForms。如果有的话,我会对p / invoke解决方案感到满意。
我在发帖前做了详尽的搜索。没有类似的问题有用。
答案 0 :(得分:4)
您可以使用Control.ClientRectangle。您需要做的是在走树时获取每个控件的屏幕边界,并计算交叉点。
它将是这样的:
Control c = myControl;
var rect = c.RectangleToScreen(c.ClientRectangle);
while (c != null) {
rect = Rectangle.Intersect(rect, c.RectangleToScreen(c.ClientRectangle));
c = c.Parent;
}
rect = myControl.RectangleToClient(rect);
现在这应该适合你,但是为了解决你决定何时绘制省略号的问题,我建议引入更好的控制大小。如果每个控件都适当地调整大小通常会更好,这样它所需的所有信息都是它自己的大小来决定如何绘制它的内容。
您描述的问题是典型的自动尺寸方案。您希望它自动调整大小,但在容器太小时也会受到限制。我尝试尽可能避免自动调整大小,而是通过重写OnSizeChanged来使用Dock属性和自定义布局登录。这可能会或可能不会达到您所需要的效果。