8

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ソリューションに満足しています。

投稿する前に徹底的な検索を行いました。同様の質問はどれも役に立ちません。

4

1 に答える 1

6

これには、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プロパティとカスタムレイアウトログインを使用するようにしています。しかし、これはあなたが必要とするもののためにうまくいくかもしれないし、うまくいかないかもしれません。

于 2012-05-11T07:38:33.357 に答える