Dot-Net

你能得到一個剪輯控制項的可見區域的大小嗎?

  • July 19, 2016

有沒有辦法在 WinForms 中獲取剪輯控制項的可見部分的大小?

一個很簡單的例子:在窗體上放置一個控制項,並使窗體寬度小於控制項寬度。你如何獲得控制項可見區域的寬度?在這種情況下,您可以使用表單的 ClientSize,但並不總是那麼簡單。

一個更複雜(和真實)的例子:我有一個 AutoSize 設置為 true 的標籤,它可以增長到超出其包含控制項的寬度,導致它被剪裁。當這種情況發生時,我需要知道。這並不像比較標籤的寬度與其容器的寬度那麼簡單,因為容器也可能有 AutoSize = true 並且也會被裁剪。

目前我的方法是沿著容器樹向上走,直到找到一個 AutoSize = false 的容器,並獲得它的寬度。我還必須考慮每個容器的填充。但這僅考慮控制項被其容器或其容器的容器等裁剪。如果有問題的控制項或任何容器被具有更高 Z 順序的同級控制項裁剪,則它將不起作用。我懷疑還有其他方法可以輕鬆打破這種方法。

將標籤 AutoSize 更改為 false 不是一種選擇。標籤位於設置為 AutoSize 的 UserControl 上,因此當標籤增長時,UserControl 也會隨之增長。在不使用 AutoSize 的情況下讓它工作很痛苦。

我嘗試使用的東西,但沒有成功:

Control.ClientSize, Control.ClientRectangle, Control.PreferredSize, Control.CreateGraphics().VisibleClipBounds.

我已經玩了一點圖形類,但我在那裡過頭了。Graphics.VisibleClipBounds聽起來很有希望,但似乎總是返回與提到的其他大小屬性相同的值。

這特別適用於 WinForms。如果僅此而已,我會對 ap/invoke 解決方案感到滿意。

在發布之前,我確實做了詳盡的搜尋。類似的問題都沒有幫助。

您可以為此使用 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 屬性和自定義佈局登錄。不過,這可能會或可能不會滿足您的需求。

引用自:https://stackoverflow.com/questions/10508179