C#グループボックス - ボーダー /キャプションのルックアンドフィールのカスタマイズ

StackOverflow https://stackoverflow.com/questions/4056714

  •  27-09-2019
  •  | 
  •  

質問

もう少しカスタマイズしたい2つのグループボックスがあります。ラベル付きのパネルを持っていることに頼りたくありません(これは、パネルと親のコントロールに同じ背景色が必要であることを意味します。ラベルには、テキストの背後にある境界線を覆う色が設定されている必要があるため、境界線が欲しかったのです。

ペイントイベントをキャプチャし、次のコードを使用することで、境界色の色を変更することができました。

Graphics gfx = e.Graphics;
Pen p = new Pen(Color.FromArgb(86, 136, 186), 3);

GroupBox gb = (GroupBox)sender;
Rectangle r = new Rectangle(0, 0, gb.Width, gb.Height);

gfx.DrawLine(p, 0, 5, 0, r.Height - 2);
gfx.DrawLine(p, 0, 5, 10, 5);
gfx.DrawLine(p, 62, 5, r.Width - 2, 5);
gfx.DrawLine(p, r.Width - 2, 5, r.Width - 2, r.Height - 2);
gfx.DrawLine(p, r.Width - 2, r.Height - 2, 0, r.Height - 2);

私の問題は、このように、キャプションが長すぎる場合、国境と重複するということです。それは上部の左手の境界線と重複するので、2番目を調整するだけで簡単に解決できます DrawLine ライン。ただし、境界線を適切に配置できるように、テキストのxと幅の測定値を検出したいと思います。

誰かがこれを行う方法を知っていますか?私はしばらくの間Googleを見ましたが、私には何も飛び出しません。キャプションが設定されていることはわかっています GroupBox.Text.

また、私が必要とする他の測定値がある場合は、境界線の厚さも変えていることに基づいて、フォントが小さいが、境界線が10ピクセルの半分の途中である場合に奇妙に見えることに基づいて...

前もって感謝します。

よろしく、

リチャード

役に立ちましたか?

解決

あなたが知っているように、文字列のサイズを簡単に取得するのは簡単です。しかし、私はコントロールをサブクラス化するのがはるかに簡単だと思います。 デザイン時間サポートを提供します。これが例です:

public class GroupBoxEx : GroupBox
{
    SizeF sizeOfText;
    protected override void OnTextChanged(EventArgs e)
    {
        base.OnTextChanged(e);
        CalculateTextSize();            
    }

    protected override void OnFontChanged(EventArgs e)
    {
        base.OnFontChanged(e);
        CalculateTextSize();
    }

    protected void CalculateTextSize()
    {
        // measure the string:
        using (Graphics g = this.CreateGraphics())
        {
            sizeOfText = g.MeasureString(Text, Font);
        }
        linePen = new Pen(Color.FromArgb(86, 136, 186), sizeOfText.Height * 0.1F);
    }

    Pen linePen;

    protected override void OnPaint(PaintEventArgs e)
    {
        // Draw the string, we now have complete control over where:

        Rectangle r = new Rectangle(ClientRectangle.Left + Margin.Left, 
            ClientRectangle.Top + Margin.Top, 
            ClientRectangle.Width - Margin.Left - Margin.Right, 
            ClientRectangle.Height - Margin.Top - Margin.Bottom);

        const int gapInLine = 2;
        const int textMarginLeft = 7, textMarginTop = 2;

        // Top line:
        e.Graphics.DrawLine(linePen, r.Left, r.Top, r.Left + textMarginLeft - gapInLine, r.Top);
        e.Graphics.DrawLine(linePen, r.Left + textMarginLeft + sizeOfText.Width, r.Top, r.Right, r.Top);
        // and so on...

        // Now, draw the string at the desired location:            
        e.Graphics.DrawString(Text, Font, Brushes.Black, new Point(this.ClientRectangle.Left + textMarginLeft, this.ClientRectangle.Top - textMarginTop));
    }
}

コントロールはもうペイントしないことに気付くでしょう。プロセス全体を担当しています。これにより、テキストがどこに描かれるかを正確に知ることができます - あなたはそれを自分で描画しています。

(また、線は文字列の高さの1/10であることに注意してください。)

他のヒント

さて、私は今、テキストの長さを取得する方法を見つけました...私は以下を使用しました:

SizeF textsize = gfx.MeasureString(gb.Text, gb.Font);

GFXはグラフィックスで、GBはグループボックスです。ただし、パネルから継承する独自のカスタムクラスを書くだけで、ラベルを追加する価値があると思います。その後、ラベル1、5、10、200、254などのピクセルを配置するように伝えることができます。また、パーセンテージでも。標準的な境界線をオーバーライドできないこともわかりました。これは、境界線が1pxの場合、境界線を介して表示されます。GroupBoxを使用することはもう1つの不利です。

よろしく、

リチャード

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top