渐变面板在最小化时显示红叉,然后恢复

我不知道为什么会这样,但我创建了下面的代码,它是一个渐变面板,然后面板停靠在屏幕的左边。

当窗体重新resize时,它会正确显示,但是如果最小化窗体然后恢复它,则会得到一个大的红色X而不是渐变。

谁能发现错误?

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Drawing2D; using System.Text; using System.Windows.Forms; public class GradientPanel : Panel { private Color ColorA = Color.LightBlue; private Color ColorB = Color.Red; private LinearGradientMode GradientFillStyle = LinearGradientMode.ForwardDiagonal; private Brush gradientBrush; 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(); } } public GradientPanel() { handlerGradientChanged = new EventHandler(GradientChanged); ResizeRedraw = true; } private EventHandler handlerGradientChanged; protected override void OnPaintBackground(System.Windows.Forms.PaintEventArgs e) { gradientBrush = new LinearGradientBrush(ClientRectangle, ColorA, ColorB, GradientFillStyle); e.Graphics.FillRectangle(gradientBrush, ClientRectangle); } protected override void Dispose(bool disposing) { if (disposing) { if (gradientBrush != null) gradientBrush.Dispose(); } base.Dispose(disposing); } protected override void OnResize(EventArgs eventargs) { Invalidate(); //base.OnResize(eventargs); } protected override void OnSizeChanged(EventArgs e) { Invalidate(); //base.OnSizeChanged(e); } private void GradientChanged(object sender, EventArgs e) { if (gradientBrush != null) gradientBrush.Dispose(); gradientBrush = null; Invalidate(); } } 

我会避免在OnPaintBackground处理程序中创建一个新的LinearGradientBrush

我的猜测是你可能会达到你的GDI对象限制(你可以检查任务管理器),因为我认为你没有正确处理你的刷子。

将其移动到构造函数,或者在颜色和样式属性更改时调用的函数(并在创建新属性之前处置之前)

这是一个例子,你可以做什么,同时仍然允许属性改变颜色等…

编辑属性:

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

添加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(); } 

我正在做类似的事情,但即使清理LinearGradientBrush也没有为我修复它。 查看控制台输出,我注意到“System.Drawing.dll中出现System.ArgumentException类型的第一次机会exception”。 我相信这是因为当组件最小化时ClientRectangle为0,0。 添加此代码似乎为我解决了这个问题:

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

看起来你没有正确处理画笔。

重构代码:

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

您不必在每个Resize或SizeChanged上无效,因为您已经拥有ResizeRedraw=True属性的控件集。 我还添加了DoubleBuffered=True属性来控制闪烁。

我将Gradient画笔放在Using()块中,以便它被处理掉。