New area does not redraw when user size increases

I think I missed something trivial here. I got a simple control directly from Control . I override OnPaint and draw a rectangle ( e.Graphics.DrawRectangle ) and the text inside it ( e.Graphics.DrawString ). I did not redefine the other members.

It worked well when the control was resized to a smaller size, but when it gets larger, the new area does not repaint properly. As soon as I resize it to a smaller size again, even if it is one pixel, everything will display correctly.

OnPaint is called correctly (with the corresponding PaintEventArgs.ClipRectangle set correctly to the new area), but the new area is not painted (artifacts appear) in any case.

What am I missing?

EDIT:

code:

 protected override void OnPaint(PaintEventArgs e) { // Adjust control height based on current width, to fit current text: base.Height = _GetFittingHeight(e.Graphics, base.Width); // Draw frame (if available): if (FrameThickness != 0) { e.Graphics.DrawRectangle(new Pen(FrameColor, FrameThickness), FrameThickness / 2, FrameThickness / 2, base.Width - FrameThickness, base.Height - FrameThickness); } // Draw string: e.Graphics.DrawString(base.Text, base.Font, new SolidBrush(base.ForeColor), new RectangleF(0, 0, base.Width, base.Height)); } private int _GetFittingHeight(Graphics graphics, int width) { return (int)Math.Ceiling(graphics.MeasureString(base.Text, base.Font, width).Height); } 

WTF?

+4
source share
2 answers

Try adding this to your constructor:

 public MyControl() { this.ResizeRedraw = true; this.DoubleBuffered = true; } 

and in your drawing event clear the previous drawing:

 protected override void OnPaint(PaintEventArgs e) { e.Graphics.Clear(SystemColors.Control); // yada-yada-yada } 
+7
source

While ResizeRedraw will work, it forces the entire control to redraw for each resize event, not just draw the area that was detected by the resize. This may or may not be desirable.

The problem the OP is facing is that the old rectangle is not invalidated; only the identified area is repainted, and the old graphics remain where they were. To fix this, determine if the size of your rectangle has increased vertically or horizontally and the corresponding edge of the rectangle is invalid.

How specific you would like it to be will depend on your implementation. You will need to have something that erases the old edge of the rectangle, and you will need to call Invalidate , passing in the area containing the old edge of the rectangle. It can be a little tricky to get it working correctly, depending on what you are doing, and using ResizeRedraw in the end can be a lot simpler if the performance difference is small.

Just for example, here is what you can do for this problem when drawing a border.

 // member variable; should set to initial size in constructor // (side note: should try to remember to give your controls a default non-zero size) Size mLastSize; int borderSize = 1; // some border size ... // then put something like this in the resize event of your control var diff = Size - mLastSize; var wider = diff.Width > 0; var taller = diff.Height > 0; if (wider) Invalidate(new Rectangle( mLastSize.Width - borderSize, // x; some distance into the old area (here border) 0, // y; whole height since wider borderSize, // width; size of the area (here border) Height // height; all of it since wider )); if (taller) Invalidate(new Rectangle( 0, // x; whole width since taller mLastSize.Height - borderSize, // y; some distance into the old area Width, // width; all of it since taller borderSize // height; size of the area (here border) )); mLastSize = Size; 
+1
source

Source: https://habr.com/ru/post/1438845/


All Articles