I want to make a panel have a thick border. Can I set this somehow?

20,350

Solution 1

Jim,

I've made a user control and given is a ParentControlDesigner. As I indicated in my comment it's not a perfect solution to what you're asking for. But it should be a good starting point. Oh any FYI, I've got it with a customizable border color too. I was inspired by another SO post to pursue this... It was trickier than I expected. To get things to rearrange correctly when setting the border size a call to PerformLayout is made. The override to DisplayRectangle and the call to SetDisplayRectLocation in OnResize cause the proper repositioning of the child controls. As well the child controls don't have the expected "0,0" when in the upper left most... unless border width is set to 0... And OnPaint provides the custom drawing of the border.

Best of luck to ya! Making custom controls that are parents is tricky, but not impossible.

[Designer(typeof(ParentControlDesigner))]
public partial class CustomPanel : UserControl
{
    Color _borderColor = Color.Blue;
    int _borderWidth = 5;

    public int BorderWidth
    {
        get { return _borderWidth; }
        set { _borderWidth = value; 
            Invalidate();
            PerformLayout();
        }
    }

    public CustomPanel()  { InitializeComponent(); }

    public override Rectangle DisplayRectangle
    {
        get 
        { 
            return new Rectangle(_borderWidth, _borderWidth, Bounds.Width - _borderWidth * 2, Bounds.Height - _borderWidth * 2); 
        }
    }

    public Color BorderColor
    {
        get { return _borderColor; }
        set { _borderColor = value; Invalidate(); }
    }

    new public BorderStyle BorderStyle
    {
        get { return _borderWidth == 0 ? BorderStyle.None : BorderStyle.FixedSingle; }
        set  { }
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaintBackground(e);
        if (this.BorderStyle == BorderStyle.FixedSingle)
        {
            using (Pen p = new Pen(_borderColor, _borderWidth))
            { 
                Rectangle r = ClientRectangle; 
                // now for the funky stuff...
                // to get the rectangle drawn correctly, we actually need to 
                // adjust the rectangle as .net centers the line, based on width, 
                // on the provided rectangle.
                r.Inflate(-Convert.ToInt32(_borderWidth / 2.0 + .5), -Convert.ToInt32(_borderWidth / 2.0 + .5));
                e.Graphics.DrawRectangle(p, r);
            }
        }
    }

    protected override void OnResize(EventArgs e)
    {
        base.OnResize(e);
        SetDisplayRectLocation(_borderWidth, _borderWidth);
    }
}

Solution 2

This is an old post but I still find it useful. And I just found another way.

ControlPaint.DrawBorder(e.Graphics, control.ClientRectangle,
                        Color.Black, BORDER_SIZE, ButtonBorderStyle.Inset,
                        Color.Black, BORDER_SIZE, ButtonBorderStyle.Inset,
                        Color.Black, BORDER_SIZE, ButtonBorderStyle.Inset,
                        Color.Black, BORDER_SIZE, ButtonBorderStyle.Inset);

Solution 3

Just implement the panel's Paint event and draw a border. For example:

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;

namespace WindowsFormsApplication1 {
  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
      panel1.Paint += panel1_Paint;
    }
    VisualStyleRenderer renderer = new VisualStyleRenderer(VisualStyleElement.Button.PushButton.Normal);

    private void panel1_Paint(object sender, PaintEventArgs e) {
      renderer.DrawEdge(e.Graphics, panel1.ClientRectangle,
        Edges.Bottom | Edges.Left | Edges.Right | Edges.Top,
        EdgeStyle.Raised, EdgeEffects.Flat);
    }
  }
}

Play around with the arguments to find something you like. You ought to add code to fallback to ControlPaint.DrawBorder if visual styles aren't enabled. Meh.

Solution 4

If this is just about presentation, put a panel that fills the form with a background color of the border color you want and a Dock style of Fill. Place another panel inside this one with the standard background color and a Dock style of Fill. Play with Padding and Margin of the two panels to get the border size you wish (I forget which param applies correclty to the inner panel and the outer panel). Place your controls on the interior panel. With both panels set to Dock=Fill, form resizing is automatically handled for you. You may need to experiment with some of the controls, but I have done this many times with no issues for both application main windows and popup forms.

Share:
20,350
jim
Author by

jim

uhhh

Updated on July 09, 2022

Comments

  • jim
    jim almost 2 years

    I want to make a panel have a thick border. Can I set this somehow?

    PS, I am using C#. VS 2008.