33

Well, I'm coding the OnPaint event for my own control and it is very nescessary for me to make it pixel-accurate.

I've got a little problem with borders of rectangles.

See picture:

removed dead ImageShack link

These two rectangles were drawn with the same location and size parameters, but using different size of the pen. See what happend? When border became larger it has eaten the free space before the rectangle (on the left).

I wonder if there is some kind of property which makes border be drawn inside of the rectangle, so that the distance to rectangle will always be the same. Thanks.

SuperBiasedMan
  • 9,814
  • 10
  • 45
  • 73
undsoft
  • 789
  • 2
  • 12
  • 21

4 Answers4

67

You can do this by specifying PenAlignment

Pen pen = new Pen(Color.Black, 2);
pen.Alignment = PenAlignment.Inset; //<-- this
g.DrawRectangle(pen, rect);
hultqvist
  • 17,451
  • 15
  • 64
  • 101
  • 3
    One caveat I found; if a border is 1 pixel wide, it will not be drawn on the right and bottom side. I fixed it by specifying the rectangle like this (substract 1 pixel from width and height if pen width is 1 pixel wide): New Rectangle(0, 0, width - If(pen.Width > 1, 0, 1), height - If(pen.Width > 1, 0, 1))) – okkko Jan 08 '20 at 10:13
9

If you want the outer bounds of the rectangle to be constrained in all directions you will need to recalculate it in relation to the pen width:

private void DrawRectangle(Graphics g, Rectangle rect, float penWidth)
{
    using (Pen pen = new Pen(SystemColors.ControlDark, penWidth))
    {
        float shrinkAmount = pen.Width / 2;
        g.DrawRectangle(
            pen,
            rect.X + shrinkAmount,   // move half a pen-width to the right
            rect.Y + shrinkAmount,   // move half a pen-width to the down
            rect.Width - penWidth,   // shrink width with one pen-width
            rect.Height - penWidth); // shrink height with one pen-width
    }
}
Fredrik Mörk
  • 155,851
  • 29
  • 291
  • 343
2

This isn't a direct answer to the question, but you might want to consider using the ControlPaint.DrawBorder method. You can specify the border style, colour, and various other properties. I also believe it handles adjusting the margins for you.

Noldorin
  • 144,213
  • 56
  • 264
  • 302
  • Though it does draw the border right way, for some readon this function uses considerably more processor time than DrawRectangle. – undsoft May 30 '09 at 11:56
  • @undsoft: Yeah, I wouldn't be too surprised. I'm not sure how it works behind the scenes, but it's certainly a lot more complicated than DrawRectangle, given that's it's capable of drawing 3D and other style borders, among other things. – Noldorin May 30 '09 at 12:23
0

I guess not... but you may move the drawing position half the pen size to the bottom right

Scoregraphic
  • 7,110
  • 4
  • 42
  • 64