web-dev-qa-db-ja.com

Winforms / C#のテキストの量とフォントサイズに基づいてラベルサイズを決定する

この問題に対するより良いアプローチがあるかどうか知りたい。ラベルのサイズを(垂直方向に)一定のテキスト量に合わせて変更したい。ラベルの幅は固定(折り返さなければならない前に約60文字)、約495ピクセルです。フォントも固定サイズ(12ポイントはafaik)ですが、テキストはそうではありません。

私がしたいのは、「改行」がある場合、またはテキストを折り返す必要がある場合にラベルの高さを増やすことです。アイデアは、テキストがラベルで完全に見えるようにすることです。 AutoSizeは、高さではなく幅が大きくなるため機能しません。

もちろん、NewLinesの数をカウントして追加することもできます:Newlines * LineHeight、そして-行ごとに60文字を入れることができたら、文字数を分割し、必要なだけLineHeightピクセルを追加します。

もっとプロフェッショナルな方法があるのだろうかと思っていました。私のアプローチも「ラメ」ですか?

前もって感謝します。

40

Graphics.MeasureString、文字列、フォント、および最大幅を受け入れるオーバーロードで?これはSizeFを返すので、Heightを四捨五入できます。

        using(Graphics g = CreateGraphics()) {
            SizeF size = g.MeasureString(text, lbl.Font, 495);
            lbl.Height = (int) Math.Ceiling(size.Height);
            lbl.Text = text;
        }
91
Marc Gravell

System.Drawing.Graphicsには、この目的に使用できるMeasureStringメソッドがあります。文字列、フォント、およびint "width"パラメーターを受け取るオーバーロードを使用します。この最後のパラメーターは、文字列に許可される最大幅を指定します-このパラメーターにはラベルの設定幅を使用します。

MeasureStringは、SizeFオブジェクトを返します。この返されたオブジェクトのHeightプロパティを使用して、ラベルの高さを設定します。

注:この目的でGraphicsオブジェクトを取得するには、this.CreateGraphicsを呼び出すことができます。

33
MusiGenesis

Graphics.MeasureString()はおそらく役立つでしょう。

これは、Control.CreateGraphics()呼び出しを使用するための唯一のユースケースの1つでもあります。

9
Quibblesome
Size maxSize = new Size(495, int.MaxValue);
_label.Height = TextRenderer.MeasureText(_label.Text , _label.Font, maxSize).Height;
5
Hacko

この「答え」は、将来の参照のためであり、AutoSize = trueがそれ(WinFormsラベル)の高さが決して大きくならないことを意味するという最初の仮定と戦うためです。

次のリンクは、MaximumSizeなどの他のプロパティでのAutoSize = trueのさまざまな効果を示しています。予想される質問の用途によっては、これらのアプローチのいずれかに従うことが適切な場合があります。

http://blogs.msdn.com/jfoscoding/articles/478299.aspx

2
user166390

私はここで受け入れられた答えにこの問題を解決するユーザーコントロールを投稿しました: テキストボックスコントロールのフォントをオートスケールして、可能な限り大きくし、テキストエリアの境界に収まるようにします

コントロールはRichTextBoxを拡張します。メソッドには、すべてのテキストが収まるようにフォントを自動的にサイズ変更するScaleFontToFitがあります。

すてきなことは、複数行のプロパティを尊重することです。それが本当なら、それは言葉が折り返すことを可能にし、そうでなければそれはしません。

1
blak3r

MeasureString()のオーバーライドメソッドを持たないコンパクトフレームワークを使用する必要がある場合は、自分で高さを計算することを検討してください。

private int YukseklikAyarla(string p, Font font, int maxWidth)
    {
        int iHeight = 0;
        using (Graphics g = CreateGraphics())
        {
            var sizes = g.MeasureString(p, font); // THE ONLY METHOD WE ARE ALLOWED TO USE
            iHeight = (int)Math.Round(sizes.Height);
            var multiplier = (int)Math.Round((double)sizes.Width) / maxWidth; // DIVIDING THE TEXT WIDTH TO SEE HOW MANY LINES IT CAN HAS
            if (multiplier > 0)
            {
                iHeight = (int)(iHeight * (multiplier + 1)); // WE ADD 1 HERE BECAUSE THE TEXT ALREADY HAS A LINE
            }
        }
        return iHeight;
    }
0
Doğa Gençer

TextRenderer クラスを使用して、Marcの応答のように文字列を測定して、Graphicsオブジェクトなどを作成する代わりに何か欠点がありますか?

0
jean

60文字はテストテキストに有効かもしれませんが、すべての文字が同じ幅ではありません。たとえば、比較
llllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
そして
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww

どちらも60文字ですが、幅は大きく異なります。

0
Yuliy

この記事 によると、最終出力にWindowsフォームコントロールを使用する場合は、TextRendererを使用する必要があります。 TextRendererとGraphics.MeasureStringの結果は異なるため、出力の最終モードに一致する結果を使用してください。

0
Barry Keller