1

もう少しカスタマイズしたい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);

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

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

また、境界線の太さも変更しているので、フォントが小さいのに境界線が半分下から10ピクセルだった場合に奇妙に見えることに基づいて、他に必要な測定値があるかどうかも教えてください...

前もって感謝します。

よろしく、

リチャード

4

2 に答える 2

2

あなたが知っているように、文字列のサイズを取得するのは簡単です。しかし、コントロールのサブクラス化ははるかに簡単で、見栄えが良くなり、設計時のサポートが得られると思います。次に例を示します。

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であることに注意してください。)

于 2010-10-30T01:38:20.113 に答える
0

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

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

gfx は Graphics で、gb は GroupBox です。ただし、Panel から継承する独自のカスタム クラスを記述し、それにラベルを追加するだけの価値があると思います。そうすれば、ラベル 1、5、10、200、254 などのピクセルを配置するように指示できます。またはまた、標準の境界線をオーバーライドできないこともわかりました-境界線が1pxの場合、追加した境界線を通してまだ表示されます-GroupBoxを使用するもう1つの欠点です。

よろしく、

リチャード

于 2010-10-30T00:54:20.393 に答える