How to change Panel Border Color
Asked Answered
R

6

32

In the properties of a Panel I have set the border style to Fixed Single.
When I am running my application it has the color gray. I don't know how to change the border color.

I have tried this in the Paint event handler of the panel:

private void HCp_Paint(object sender, PaintEventArgs e)
{
    Panel p = sender as Panel;
    ControlPaint.DrawBorder(e.Graphics, p.DisplayRectangle, Color.Yellow, ButtonBorderStyle.Inset);
}
        

This displays the border like this:

Screenshot of actual result

but I want a fixed single border like this:

Screenshot of desited result

How I make the border in yellow?

Rolling answered 8/1, 2014 at 12:47 Comment(0)
P
29

If you don't want to make a custom panel as suggested in @Sinatr's answer you can draw the border yourself:

private void panel1_Paint(object sender, PaintEventArgs e)
{
     ControlPaint.DrawBorder(e.Graphics, this.panel1.ClientRectangle, Color.DarkBlue, ButtonBorderStyle.Solid);
}
Pool answered 13/11, 2018 at 14:25 Comment(1)
And if you want to control the thickness: private void panel1_Paint(object sender, PaintEventArgs e) { Color col = Color.DarkBlue; ButtonBorderStyle bbs = ButtonBorderStyle.Solid; int thickness = 4; ControlPaint.DrawBorder(e.Graphics, this.panel1.ClientRectangle, col, thickness, bbs, col, thickness, bbs, col, thickness, bbs, col, thickness, bbs); }Palisade
C
17

You can create own Panel class and draw border in the client area:

[System.ComponentModel.DesignerCategory("Code")]
public class MyPanel : Panel
{
    public MyPanel() 
    {
        SetStyle(ControlStyles.UserPaint | ControlStyles.ResizeRedraw | ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        using (SolidBrush brush = new SolidBrush(BackColor))
        {
            e.Graphics.FillRectangle(brush, ClientRectangle);
        }

        e.Graphics.DrawRectangle(Pens.Yellow, 0, 0, ClientSize.Width - 1, ClientSize.Height - 1);
    }

}
Chokecherry answered 8/1, 2014 at 13:31 Comment(7)
I often put border painting in OnPaintBackground just to keep the frequency down.Tailwind
Hi Sinatr, can you please explain where to write this code? I am not getting where to write this code I am new, pls tell the entire process.Rolling
This solution works, but if you have a control in the panel that is set to dock.fill (for example), it overlaps on top of the rectangle and the rectangle is hidden. Anyway to set the panel's "usable space" to within the rectangle so that controls within don't overlap the rectangle?Rover
@JPProgrammer, Dock.Fill can be easily replaced with anchoring (set content control location and anchor Left | Top | Right | Bottom), so that content will not cover drawn in client region border lines. Do not use Dock.Fill.Chokecherry
@Chokecherry - I just gave setting the Location and Anchor a try but couldn't get it to work easily. Setting the location allows the left and top borders to show, but the right and bottom borders get overlapped. I guess I would have set the size (and continually resize the content whenever the panel resized) to get it to show the right and bottom borders? In my case I set the padding of the panel to the width of the border and got it to work (works using Dock.Fill or Anchor).Rover
This answer is WRONG. I don't undestand why I find wo many wrong answers on Stackoverflow that have been up-voted? A border must NEVER be drawn into the CLIENT area. A border is part of the NON-CLIENT area and if you draw it into the client area it will be inside the scrollbars and when scrolling you get crap on the screen!Badtempered
@Elmue, that's called workaround. I agree it has drawbacks, e.g. it's necessary to take care about content not overlapping drawn border, yet it's very easy and for some it may be an acceptable solution. I guess answer was upvoted by those.Chokecherry
L
10

If you don't want to go to the trouble of sub-classing a panel, you can just create another panel 2 pixels bigger in each dimension, make it the border color and sit it directly behind the panel that needs a border. This is just a few clicks in the IDE ...

Lotz answered 18/9, 2017 at 8:53 Comment(0)
R
4

I found this post useful

I also set the padding of the panel to the thickness of the border so that controls inside the panel don't overlap the border and hide it. In my case, I wasn't using the padding otherwise so it was a good solution, but things might get more tricky if you also plan on using the padding for more than just showing the border...

Rover answered 23/1, 2015 at 8:23 Comment(5)
This is great solution, but there is small problem when you have ScrollBar in your Panel. Then you should make also handler for Scroll event. Same like for Resize.Premolar
This answer is WRONG. I don't undestand why I find wo many wrong answers on Stackoverflow that have been up-voted? A border must NEVER be drawn into the CLIENT area. A border is part of the NON-CLIENT area and if you draw it into the client area it will be inside the scrollbars and when scrolling you get crap on the screen!Badtempered
I don't know what you're on about @Elmue, but this solution worked perfectly well for me (and others too, apparently). The question is simply about how to change the border colour around a panel, nothing about non-client areas or scrollbars (btw are you trying to say all controls in the client area should never have a border around them??). If you can provide a better solution we're all ears, but I suspect you just like spouting criticism without having any better answers yourself.Rover
Your knowledge about Windows programming is insufficient. Whatever you do in a Paint event handler or in OnPaint() will only affect the client area of the control. But the scrollbars are part of the non-client area, and a Panel is derived from ScrollableControl! So if your control has scrollbars you will paint your border INSIDE the scrollbars which is surely the wrong solution. If you want to do it correctly it is far more complicated. You will have to handle WM_NCCALCSIZE to define the width of your border and WM_NCPAINT to draw your border. Search the MSDN for that and study it!Badtempered
Sorry but Elmue is right. While this will draw a border, it will have the same effect as e.Graphics.DrawRectange() in the OnPaint() event. This is not a correct answer, placing controls inside the panel and docking items will overlap the border.Borderland
P
1

This also worked for me:

private void HCp_Paint(object sender, PaintEventArgs e)
{
    Panel p = sender as Panel;
    ControlPaint.DrawBorder(e.Graphics, p.DisplayRectangle, Color.Yellow, ButtonBorderStyle.Solid);
}

The problem of the border style is due to the ButtomBorderStyle option "Inset". By selecting "ButtonBorderStyle.Solid" you get a single line (also dotted, dashed... are available).

For many panels, I agree that the best solution is to create your own class that inherits from Panel and overwrite the Paint method...

Putup answered 29/4, 2021 at 6:17 Comment(0)
O
0

After a workaround when creating my custom panel. I was forced to apply another tweak to solve the border overlapping when the size of the child control(s) > size of the panel. In the tweak, instead of the panel drawing its border, its drawn by the parent control.

    Public Class SharpPanel : Inherits Panel
      Sub New()
        Padding = New Padding(2)
        SetStyle(ControlStyles.SupportsTransparentBackColor, True)
        SetStyle(ControlStyles.ResizeRedraw, True)
        SetStyle(ControlStyles.UserPaint, True)
        SetStyle(ControlStyles.AllPaintingInWmPaint, True)
        SetStyle(ControlStyles.ContainerControl, True)
        SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
        SetStyle(ControlStyles.ContainerControl, True)
        Width = 100
        Height = 100
        TabStop = False
     End Sub
     Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
        MyBase.OnPaint(e)
        Dim p As Control = Me.Parent
        Dim gr As Graphics = p.CreateGraphics
        Dim rec As Rectangle = Me.ClientRectangle
        If Me.VerticalScroll.Visible Then
            rec.Width = rec.Width + SystemInformation.VerticalScrollBarWidth
        End If
        If Me.HorizontalScroll.Visible Then
            rec.Height = rec.Height + SystemInformation.HorizontalScrollBarHeight
        End If
        rec.Location = Me.Location
        rec.Inflate(1, 1)
        gr.DrawRectangle(New Pen(Color.Pink), rec)
End sub
End Class
Oyler answered 25/11, 2018 at 18:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.