Pucho Pucho - 25 days ago 19
C# Question

C# LinearGradientBrush glitch when minimizing screen

I have the following code to create a blended background on my winform:

public partial class Aging : Form
{
protected override void OnPaintBackground(PaintEventArgs e)
{
using (var brush = new LinearGradientBrush(this.ClientRectangle,
Color.Transparent, Color.Transparent, LinearGradientMode.Vertical))
{
var blend = new ColorBlend();
blend.Positions = new[] { 0, 3 / 10f, 1 };
blend.Colors = new[] { Color.WhiteSmoke, Color.LightSteelBlue, Color.LightSteelBlue };
brush.InterpolationColors = blend;
e.Graphics.FillRectangle(brush, this.ClientRectangle);
}
}


The result is a color background that fades from LightSteelBlue to WhiteSmoke:

enter image description here

The problem is that if I minimize the screen and then, maximize, the application no longer shows the background:

enter image description here

This is the exception message I'm getting:

System.ArgumentException: Rectangle '{X=0,Y=0,Width=0,Height=0}' cannot have a width or height equal to 0.
at System.Drawing.Drawing2D.LinearGradientBrush..ctor(Rectangle rect, Color color1, Color color2, LinearGradientMode linearGradientMode)
at AgingStatusDb.Aging.OnPaintBackground(PaintEventArgs e)
at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
at System.Windows.Forms.Control.WmEraseBkgnd(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.Form.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg,
IntPtr wparam, IntPtr lparam)


I'm not that savvy and I'm not been able to figure out the source of the glitch. Any help would be appreciated.

Answer

To resolve the exception, just follow what the exception message said:

Rectangle '{X=0,Y=0,Width=0,Height=0}' cannot have a width or height equal to 0.

So you can simply check if ClientRectangle.Width==0 or ClientRectangle.Height==0 then do nothing and just return.

But after fixing the error you will have a black background after a minimize and restore.

If you want to draw background of a form, above code needs some corrections:

  • You need to set control to redraw itself when resized. To do so, you should set this.SetStyle(ControlStyles.ResizeRedraw, true); in constructor.

  • You need to enable double buffering to prevent flicker. So in constructor set this.DoubleBuffered = true;.

Code

public Form1()
{
    InitializeComponent();
    this.DoubleBuffered = true;
    this.SetStyle(ControlStyles.ResizeRedraw, true);
}
protected override void OnPaintBackground(PaintEventArgs e)
{
    if (ClientRectangle.Width == 0 || ClientRectangle.Height == 0) return;
    using (var brush = new LinearGradientBrush(this.ClientRectangle,
        Color.Transparent, Color.Transparent, LinearGradientMode.Vertical))
    {
        var b = new ColorBlend();
        b.Positions = new[] { 0, 3 / 10f, 1 };
        b.Colors = new[] { Color.WhiteSmoke, Color.LightSteelBlue, Color.LightSteelBlue };
        brush.InterpolationColors = b;
        e.Graphics.FillRectangle(brush, this.ClientRectangle);
    }
}
Comments