I have no idea why this is happening, but I created the below code which is a gradient panel, the panel is then docked to the left of the screen.
When the form is re
I would avoid creating a new LinearGradientBrush
in the OnPaintBackground
handler.
My guess is you could be hitting your GDI object limit (which you can check in task manager) as I don't think you are disposing your brushes correctly.
Move this to the constructor, or in a function that is called when the colours and styles properties change (and dispose of the previous before creating the new one)
Here is an example of what you can do while still allowing the properties to change the colours etc...
Edit properties:
public Color colourStart
{
get { return ColorA; }
set { ColorA = value; RefershBrush(); }
}
public Color colourEnd
{
get { return ColorB; }
set { ColorB = value; RefershBrush(); }
}
public LinearGradientMode colourGradientStyle
{
get { return GradientFillStyle; }
set { GradientFillStyle = value; RefershBrush(); }
}
Add function:
private void RefershBrush()
{
//I think this IF block should work with no problems, been a while working with brush
if(gradientBrush != null)
{
gradientBrush.Dispose();
}
gradientBrush = new LinearGradientBrush(ClientRectangle, ColorA, ColorB, GradientFillStyle);
Invalidate();
}
It doesn't look like you are disposing of the Brush correctly.
Refactored code:
public class GradientPanel : Panel {
private Color ColorA = Color.LightBlue;
private Color ColorB = Color.Red;
private LinearGradientMode GradientFillStyle = LinearGradientMode.ForwardDiagonal;
public GradientPanel() {
DoubleBuffered = true;
ResizeRedraw = true;
}
public Color colourStart {
get { return ColorA; }
set { ColorA = value; Invalidate(); }
}
public Color colourEnd {
get { return ColorB; }
set { ColorB = value; Invalidate(); }
}
public LinearGradientMode colourGradientStyle {
get { return GradientFillStyle; }
set { GradientFillStyle = value; Invalidate(); }
}
protected override void OnPaintBackground(System.Windows.Forms.PaintEventArgs e) {
using (var gradientBrush = new LinearGradientBrush(ClientRectangle, ColorA, ColorB, GradientFillStyle)) {
e.Graphics.FillRectangle(gradientBrush, ClientRectangle);
}
}
}
You don't have to invalidate on every Resize or SizeChanged because you already have the control set with the ResizeRedraw=True
property. I added the DoubleBuffered=True
property as well to control flickering.
I placed your Gradient brush in a Using()
block so that it will get disposed.
I'm doing something similar, but even cleaning up the LinearGradientBrush
didn't fix it for me. Looking at the console output, I noticed "A first chance exception of type System.ArgumentException
occurred in System.Drawing.dll." I believe this is because the ClientRectangle is 0,0 when the component is minimized. Adding this code seemed to fix it for me:
protected override void OnPaintBackground(PaintEventArgs e)
{
base.OnPaintBackground(e);
if (this.gradientBrush != null)
this.gradientBrush.Dispose();
if (this.ClientRectangle.Width > 0 && this.ClientRectangle.Height > 0)
{
this.gradientBrush = new LinearGradientBrush(this.ClientRectangle,
FROM_GRADIENT_COLOR, TO_GRADIENT_COLOR, LinearGradientMode.Horizontal);
e.Graphics.FillRectangle(this.gradientBrush, this.ClientRectangle);
}
}