C# Groupbox - 自定义边框/标题的外观

发布于 2024-09-29 10:43:34 字数 846 浏览 7 评论 0原文

我有 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);

我的问题是,像这样,如果标题太长,那么它会与边框重叠。事实上,它与顶部的左侧边框重叠 - 只需调整第二条 DrawLine 线即可轻松解决。不过,我想检测文本的 x 和宽度测量值,以便我可以正确定位边框。

有谁知道如何做到这一点?我在谷歌上查了一段时间,但什么也没引起我的注意。我知道标题是通过 GroupBox.Text 设置的。

还请说明我是否需要任何其他测量值,因为我也在更改边框厚度,所以如果字体很小但边框从中间向下开始为 10 像素,看起来会很奇怪...

提前致谢。

问候,

理查德

I have 2 groupboxes which I would like to customise a bit more, and I dont want to resort to having a panel with a label (this would mean that I would have to have the same background colour for the panel and the parent control if I wanted a border, since the label would have to have a colour set to cover up the border behind the text).

I have managed to change the border colour by capturing the paint event and using the following code:

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);

My problem is that, like this, if the caption is too long then it overlaps the border. As it is it overlaps the left hand border at the top - thats easy to solve simply by adjusting the 2nd DrawLine line. However I would like to detect the x and width measurements of the text so that I can position the borders properly.

Does anyone have any idea how to do this? I have looked on Google for a while but nothing jumps out at me. I know the caption is set through GroupBox.Text.

Please also say if there are any other measurements I may need, on the basis that I am changing the border thickness too so it would look odd if the font was tiny but the border was 10 pixels starting half way down...

Thanks in advance.

Regards,

Richard

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

悍妇囚夫 2024-10-06 10:43:34

正如我看到你已经发现的那样,很容易获得字符串的大小。但我认为子类化控件会更容易,可以提供更好的外观并为您提供设计时支持。这是一个示例:

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。)

It's easy to get the size of the string, as I see you've found out. But I think that subclassing the control would be much easier, allow for a better look and give you design time support. Here is an example:

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));
    }
}

You'll notice that the control doesn't paint itself anymore, you're in charge of the whole process. This allows you to know exactly where the text gets drawn - you're drawing it yourself.

(Note also that the line is 1/10 of the height of the string.)

撩动你心 2024-10-06 10:43:34

好吧,我现在已经找到了如何获取一段文本的长度...我使用了以下内容:

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

其中 gfx 是 Graphics,gb 是 GroupBox。不过,我认为编写自己的自定义类(继承自 Panel)可能值得,向其添加标签,然后我将能够告诉它将标签放置在 1、5、10、200、254 等像素中。或者我还发现我无法覆盖标准边框 - 如果我的边框是 1px,它仍然会通过我添加的边框显示 - 使用 GroupBox 的另一个缺点。

问候,

理查德

Well I have now found out how to get the length of a piece of text... I used the following:

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

Where gfx is Graphics and gb is a GroupBox. However I think it may be worth just writing my own custom class which inherits from Panel, adding a label to it and then I will be able to tell it to place the label 1, 5, 10, 200, 254 etc pixels in. Or even a percentage in. I also found that I couldnt override the standard border - it still shows through the border I added if my border is 1px - another disadvantage to using GroupBox.

Regards,

Richard

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文