Mistake, or am I doing something wrong? Usercontrol painting

private void UserControl1_Paint(object sender, PaintEventArgs e) { e.Graphics.DrawEllipse(Pens.Black, new Rectangle(-200, -500, this.Width + 400, this.Height + 420)); } 

Paste the above code into usercontrol. Drop usercontrol on the form and bind it to all 4 points.

In the designer (in Visual Studio 2010), it displays fine (even when resizing). Run it and try resizing the shape and the ellipse will become distorted.

Here are two examples of how, after resizing, the first while working, the second in the designer.

Running after resizeDesigner After Resize

Obviously, the behavior in the designer can not always be considered the same (although it would be nice), but I understand that the code above is completely legal. I am wrong?

+6
source share
2 answers

Stecya posted a fix, but did not provide an explanation explaining why this works, or why you see a mismatch between the designer’s behavior and the running application. In my opinion, this makes the answer minimally useful, so I thought that I would weigh with an attempt to explain.

You already know that calling the Invalidate method is a solution. What this does is tell Windows that the entire surface area of ​​the control should be redrawn the next time the window is painted. Simple enough, but why don't you do it in the designer?

The answer is that you are running the program with the Windows Aero theme enabled. Aero uses a completely new window manager called Desktop Window Manager (or DWM for short) based on composition. Each window has double buffering, which means that its graphics are displayed off-screen in a temporary bitmap, and then only on the screen. This allows you to use all sorts of cool effects and fancy transitions that users now like.

But of course, this means that partitions that have already been drawn are not erased or redrawn unless you explicitly tell Windows what to do. This is not a problem for the form inside the designer, because Aero DWM composition is not included there. When a window changes, it automatically redraws, and your swoosh looks smooth and correct.

Outside of the constructor with Aero enabled, only the newly opened parts of your control are redrawn (the rest remain in the buffer), so the form is incorrect. Part of the old shape is still present, and part of the new shape was simply drawn. The Invalidate call tells Windows "the graphical surface of this control has changed, forget everything you thought you knew about it, and redraw it from scratch time." Thus, Windows obediently obeys, discarding this part from its equalizer buffer and redrawing it from scratch, creating a properly processed, well-smoothed path.

You can make the same change in a different, more elegant way: tell the control that it needs to be redrawn every time it changes. Paste the following code into the control constructor method:

 public MyUserControl() { // Force the control to redraw itself each time it is resized this.SetStyle(ControlStyles.ResizeRedraw); } 
+7
source

You can manually disable control when resizing

 private void Form1_Resize(object sender, EventArgs e) { userControl11.Invalidate(); } 
+4
source

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


All Articles