C# LinearGradientBrush glitch when minimizing scre

2019-03-02 17:34发布

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.

2条回答
别忘想泡老子
2楼-- · 2019-03-02 17:49

There is simplest way to do fading background.

Create an image with a gradient in a graphics editor or using your code, but save it:

protected override void OnLoad(EventArgs 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;

        using (var bmp = new Bitmap(ClientRectangle.Width, ClientRectangle.Height))
        {
            var g = Graphics.FromImage(bmp);
            g.FillRectangle(brush, ClientRectangle);
            bmp.Save("background.png", ImageFormat.Png);
        }
    }
}

Run and close the app. Then remove that code.

In the end, set the form background image, which was created in the previous step:

this.DoubleBuffered = true;
this.BackgroundImageLayout = ImageLayout.Stretch;
this.BackgroundImage = new Bitmap("background.png");
查看更多
Anthone
3楼-- · 2019-03-02 17:57

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);
    }
}
查看更多
登录 后发表回答