Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FillRectangle Parameter is not valid

Tags:

c#

drawing

This is the exception I am getting

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: 

And the code

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

}

And finally the values being passed to it:

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
like image 775
Neo Avatar asked Oct 22 '13 12:10

Neo


2 Answers

You should always dispose unmanaged classes like Brush, SolidBrush, Pen. Assuming the pdt.bgColour and pdt.fgColour are of type Color, something like the following code should prevent that crash. Warning: Untested code.

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();
        }
    }
}
like image 157
sagunms Avatar answered Sep 20 '22 21:09

sagunms


Instead of creating Brush objects with each draw, perhaps you can make bgColourBrush and fgColourBrush global variables and then just change their color instead. Please forgive me if the code below doesn't compile as-is, I did this freehand. Like this:

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

UPDATE

So I see that your pdt ListCell object has a bgColour and a fgColour property. In order for my above solution to work, bgColour and fgColour need to be of type Color. Or if they are type SolidColorBrush, then you need to do this: bgColour.Color and fgColour.Color.

like image 33
Chris Leyva Avatar answered Sep 20 '22 21:09

Chris Leyva