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。问题在于另一个表单上的代码的另一部分正在处理它们。但是你的想法很好,所以我会把它作为答案,因为我最终会采用这种方法