【问题标题】:Can you get the size of the visible area of a clipped control?你能得到一个剪辑控件的可见区域的大小吗?
【发布时间】:2012-05-17 12:02:01
【问题描述】:

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

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

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

目前我的方法是沿着容器树向上走,直到找到一个 AutoSize = false 的容器,然后获取它的宽度。我还必须考虑每个容器的填充。但这仅考虑控件被其容器或其容器的容器等裁剪。如果有问题的控件或任何容器被具有更高 Z 顺序的同级控件裁剪,则它将不起作用。而且我怀疑还有其他方法可以轻松打破这种方法。

将标签 AutoSize 更改为 false 不是一种选择。标签位于设置为 AutoSize 的 UserControl 上,因此当标签增长时,UserControl 也会随之增长。在不使用 AutoSize 的情况下让它工作很痛苦。

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

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

我在 Graphics 课上玩过一点儿,但我在那儿不知所措。 Graphics.VisibleClipBounds 听起来很有希望,但似乎总是返回与提到的其他大小属性相同的值。

这特别适用于 WinForms。如果仅此而已,我会对 p/invoke 解决方案感到满意。

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

【问题讨论】:

  • 出于好奇,这个解决方案要解决什么问题?
  • @roken:我想知道标签何时比其容器宽,以便我可以添加一个工具提示来显示标签的整个文本,当且仅当整个文本不是可见的。我会使用 Label.AutoEllipsis 属性,但是当 AutoSize 为 true 时这不起作用。

标签: .net winforms graphics controls bounds


【解决方案1】:

您可以为此使用 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 属性和自定义布局登录。不过,这可能会也可能不会满足您的需求。

【讨论】:

  • 这是确定控件是否被其任何容器剪切的更好方法。它并没有严格回答我的问题,因为如果控件被兄弟剪辑,这将不起作用,但它仍然非常有帮助和教育(除非找到更好的方法,否则我会使用它)。谢谢!是的,自动调整大小可能会很痛苦。但是,当您希望容器随内容一起增长时,它非常有用。
  • 如果你想知道兄弟姐妹是如何影响它的,你可以搜索更多的控制树。
  • 是的,我需要检查每个容器中的每个控件一直到表单,同时考虑同级控件之间的 z 顺序。如果我希望它非常可靠,我将不得不查看可能与我的控制重叠的其他形式......这就是为什么如果已经存在调用来执行此操作会很好的原因。 :)
  • 这就是为什么你不这样做的原因:) 据我所知,使用 autosize 似乎并不合适。但是话又说回来,我不是拥有所有信息和要编写代码的人:)。祝你好运!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-26
  • 2011-03-13
  • 2022-08-03
  • 2012-08-13
  • 2011-12-19
  • 1970-01-01
  • 2012-01-31
相关资源
最近更新 更多