C# LinearGradientBrush glitch when minimizing screen

家住魔仙堡 提交于 2019-12-02 09:43:53

问题


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:

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

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.


回答1:


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);
    }
}



回答2:


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");


来源:https://stackoverflow.com/questions/40494234/c-sharp-lineargradientbrush-glitch-when-minimizing-screen

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!