我不知道为什么会这样,但我创建了下面的代码,这是一个渐变面板,然后面板停靠在屏幕左侧。
当窗体重新调整大小时,它会正确显示,但是如果你最小化窗体然后恢复它,你会得到一个大的红色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();
}
}
答案 0 :(得分:4)
我正在做类似的事情,但即使清理LinearGradientBrush
也无法解决这个问题。查看控制台输出,我注意到“System.Drawing.dll中出现了System.ArgumentException
类型的第一次机会异常。”我相信这是因为当组件最小化时,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);
}
}
答案 1 :(得分:2)
我会避免在LinearGradientBrush
处理程序中创建新的OnPaintBackground
。
我的猜测是你可能会达到你的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(); }
}
添加功能:
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();
}
答案 2 :(得分:1)
看起来你没有正确处理画笔。
重构代码:
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()
块中,以便它被处理掉。