C# FillRectangle参数无效
这是我得到的例外C# FillRectangle参数无效,c#,drawing,C#,Drawing,这是我得到的例外 System.ArgumentException was unhandled HResult=-2147024809 Message=Parameter is not valid. Source=System.Drawing StackTrace: at System.Drawing.Graphics.CheckErrorStatus(Int32 status) at System.Drawing.Graphics.FillRecta
System.ArgumentException was unhandled
HResult=-2147024809
Message=Parameter is not valid.
Source=System.Drawing
StackTrace:
at System.Drawing.Graphics.CheckErrorStatus(Int32 status)
at System.Drawing.Graphics.FillRectangle(Brush brush, Int32 x, Int32 y, Int32 width, Int32 height)
at System.Drawing.Graphics.FillRectangle(Brush brush, Rectangle rect)
at frmMain.drawCboxItem(Object sender, DrawItemEventArgs e) in frmMain.cs:line 465
at frmMain.cboxSectionCell_DrawItem(Object sender, DrawItemEventArgs e) in frmMain.cs:line 485
at System.Windows.Forms.ComboBox.OnDrawItem(DrawItemEventArgs e)
at System.Windows.Forms.ComboBox.WmReflectDrawItem(Message& m)
at System.Windows.Forms.ComboBox.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.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.SendMessage(HandleRef hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at System.Windows.Forms.Control.SendMessage(Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.Control.ReflectMessageInternal(IntPtr hWnd, Message& m)
at System.Windows.Forms.Control.WmOwnerDraw(Message& m)
at System.Windows.Forms.Control.WmDrawItem(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ContainerControl.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.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at System.Windows.Forms.NativeWindow.DefWndProc(Message& m)
at System.Windows.Forms.Control.DefWndProc(Message& m)
at System.Windows.Forms.Control.WmOwnerDraw(Message& m)
at System.Windows.Forms.Control.WmDrawItem(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ComboBox.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.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
InnerException:
代码呢
if (e.Index > -1)
{
e.DrawBackground();
Brush bgColourBrush = null;
Brush fgColourBrush = null;
ComboBox combo = (ComboBox)sender;
objPDT.ListCell pdt = (objPDT.ListCell)combo.Items[e.Index];
if (e.ForeColor == SystemColors.HighlightText)
{
bgColourBrush = new SolidBrush(e.BackColor);
fgColourBrush = new SolidBrush(e.ForeColor);
}
else if (pdt.bgColour == null)
{
bgColourBrush = Brushes.Black;
fgColourBrush = Brushes.White;
}
else
{
bgColourBrush = pdt.bgColour;
fgColourBrush = pdt.fgColour;
}
// background
e.Graphics.FillRectangle(bgColourBrush, e.Bounds);
//foreground
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.DrawString(pdt.Name, combo.Font, fgColourBrush, e.Bounds.X, e.Bounds.Y);
}
最后是传递给它的值:
pdt {
Section 8--> CELL} objPDT.ListCell
_bgcolour {Color = {Color [A=255, R=166, G=166, B=166]}} System.Drawing.Brush {System.Drawing.SolidBrush}
_CellID 27 int
_fgcolour {Color = {Color [A=255, R=255, G=255, B=255]}} System.Drawing.Brush {System.Drawing.SolidBrush}
_name "Section 8--> CELL" string
_SectionID 8 int
bgColour {Color = {Color [A=255, R=166, G=166, B=166]}} System.Drawing.Brush {System.Drawing.SolidBrush}
fgColour {Color = {Color [A=255, R=255, G=255, B=255]}} System.Drawing.Brush {System.Drawing.SolidBrush}
Name "Section 8--> CELL" string
Value "8:27" string
}
e.Bounds {X = 0 Y = 30 Width = 290 Height = 15} System.Drawing.Rectangle
Bottom 45 int
Height 15 int
IsEmpty false bool
Left 0 int
Location {X = 0 Y = 30} System.Drawing.Point
Right 290 int
Size {Width = 290 Height = 15} System.Drawing.Size
Top 30 int
Width 290 int
X 0 int
Y 30 int
不必在每次绘制时创建笔刷对象,也许您可以创建
bgColorBrush
和fgColorBrush
全局变量,然后只需更改它们的颜色即可。如果下面的代码没有按原样编译,请原谅,我是徒手编写的。
像这样:
if (e.Index > -1)
{
e.DrawBackground();
ComboBox combo = (ComboBox)sender;
objPDT.ListCell pdt = (objPDT.ListCell)combo.Items[e.Index];
if (e.ForeColor == SystemColors.HighlightText)
{
this.bgColourBrush.Color = e.BackColor;
this.fgColourBrush.Color = e.ForeColor;
}
else if (pdt.bgColour == null)
{
this.bgColourBrush.Color = Brushes.Black.Color;
this.fgColourBrush.Color = Brushes.White.Color;
}
else
{
this.bgColourBrush.Color = pdt.bgColour;
this.fgColourBrush.Color = pdt.fgColour;
}
// background
e.Graphics.FillRectangle(bgColourBrush, e.Bounds);
//foreground
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.DrawString(pdt.Name, combo.Font, fgColourBrush, e.Bounds.X, e.Bounds.Y);
}
更新
因此,我看到您的pdt ListCell对象具有
bgColor
和fgColor
属性。为了使我的上述解决方案正常工作,bgColour
和fgColour
的类型必须为Color
。或者,如果它们是SolidColorBrush类型,那么您需要执行以下操作:bgColour.Color
和fgColour.Color
您应该始终处理非托管类,如Brush
,SolidBrush
,Pen
。假设pdt.bgColour
和pdt.fgColour
属于Color
类型,类似于以下代码的代码应该可以防止崩溃。警告:未测试的代码
if (e.Index > -1)
{
e.DrawBackground();
SolidBrush bgColourBrush = null;
SolidBrush fgColourBrush = null;
ComboBox combo = (ComboBox)sender;
objPDT.ListCell pdt = (objPDT.ListCell)combo.Items[e.Index];
try {
if (e.ForeColor == SystemColors.HighlightText)
{
bgColourBrush = new SolidBrush(e.BackColor);
fgColourBrush = new SolidBrush(e.ForeColor);
}
else if (pdt.bgColour == null)
{
bgColourBrush = new SolidBrush(Color.Black);
fgColourBrush = new SolidBrush(Color.White);
}
else
{
bgColourBrush = pdt.bgColour;
fgColourBrush = pdt.fgColour;
}
// background
e.Graphics.FillRectangle(bgColourBrush, e.Bounds);
//foreground
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.DrawString(pdt.Name, combo.Font, fgColourBrush, e.Bounds.X, e.Bounds.Y);
} finally {
if(bgColorBrush != null) {
bgColorBrush.Dispose();
}
if(fgColorBrush != null) {
fgColorBrush.Dispose();
}
}
}
您没有调用所创建的SolidBrush对象的Dispose()方法。当您的程序已经消耗了10000个GDI对象时,这确实会以一种相当不可诊断的方式出现。当您自定义绘图时,垃圾收集器通常很难让您避免这样的麻烦。使用在使用SolidBrush时设置为true的布尔标志,并确保在设置该标志后在绘制后对其进行处理。在代码中寻找可能忘记执行此操作的其他位置。@HansPassant我不得不删除dispose,因为它完全破坏了脚本,在它移动到VS2012之前,它一直工作得很好。当您处理除您创建的SolidBrush笔刷以外的笔刷时,它肯定会破坏您的代码。这就是为什么需要使用bool标志。我检查了GDI对象,它保持在3187:s,即使设置了bool标志,它仍然会发生。令人恼火的是,如果手机ID为0,那么它就会被画得很好!因此,如果除了字符串名和int-cellid之外所有内容都是相同的,那么它就会被绘制出来,但它们与代码的这一部分无关!这个数字太高了。GDI对象堆与所有进程共享。堆本身也可能耗尽65k对象iirc。问题在于另一个表单上的代码的另一部分正在处理它们。但是你的想法很好,所以我会把它作为答案,因为我最终会采用这种方法