I want to make a panel have a thick border. Can I set this 开发者_运维知识库somehow?
PS, I am using C#. VS 2008.
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);
}
}
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.
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.
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);
This is kind of rigging it but I've always just used a label for each side border. You'll have to set the autosize property to false and dock one to each side (left, right, top, bottom). Then just set the width/height/background color to do what you want.
You could easily make this a user control and just expose some custom public properties to set the width/height for you and the background color of all the labels to change the color.
精彩评论