你能得到剪裁控件的可见区域的大小吗?

时间:2012-05-09 00:02:37

标签: .net winforms graphics controls bounds

有没有办法在WinForms中获取剪切控件的可见部分的大小?

一个非常简单的示例:在窗体上放置一个控件,使窗体宽度小于控件宽度。如何获得控件可见区域的宽度?在这种情况下,您可以使用表单的ClientSize,但并不总是那么简单。

一个更复杂(和实际)的例子:我有一个AutoSize设置为true的标签,它可以超出其包含控件的宽度,导致它被剪裁。当发生这种情况时,我需要知道。它并不像将标签的宽度与其容器的宽度进行比较那么简单,因为容器也可能具有AutoSize = true并且也会被剪裁。

目前我的方法是走向容器树,直到找到一个AutoSize = false的容器,然后获取它的宽度。我还必须考虑每个容器的填充。但是这只考虑控件被其容器或容器的容器等夹住。如果有问题的控件或任何容器被具有更高Z顺序的同级控件剪切,它将无法工作。我怀疑还有其他方法可以轻易打破这种做法。

将标签AutoSize更改为false不是一个选项。标签位于UserControl上,该控件设置为AutoSize,以便在标签增长时,UserControl随之增长。在不使用AutoSize的情况下使其工作非常痛苦。

我尝试使用的东西,但未成功:

Control.ClientSizeControl.ClientRectangleControl.PreferredSizeControl.CreateGraphics().VisibleClipBounds

我和Graphics课程玩过一点但是我在那里。 Graphics.VisibleClipBounds听起来很有希望,但似乎总是与上面提到的其他尺寸属性一样。

这特别适用于WinForms。如果有的话,我会对p / invoke解决方案感到满意。

我在发帖前做了详尽的搜索。没有类似的问题有用。

1 个答案:

答案 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属性和自定义布局登录。这可能会或可能不会达到您所需要的效果。