SolidBrush.Clone throws exception

646 Views Asked by At

I'm using different types of brushes like SolidBrush, HatchBrush, etc.., to draw complex shapes and text in my windows forms control. The code I'm using is,

protected void FillShape(Brush myBrush, GraphicsPath shape)
        {
            if (myBrush is SolidBrush)
            {
                using (SolidBrush sbr = myBrush.Clone() as SolidBrush)
                {
                    //Code for drawing with solid brush
                }
            }
            else if (myBrush is HatchBrush)
            {                    
                    //Code for drawing with hatch brush
            }
            else if (myBrush is LinearGradientBrush)
            {
                    //Code for drawing with linear gradient brush
            }
            else if (myBrush is PathGradientBrush)
            {
                    //Code for drawing with path gradient brush
            }
        }

Some times, the line myBrush.Clone() throws ArgumentException. I searched MSDN link for SolidBrush.Clone() method but there is no information about any exception SolidBrush.Clone

So, I checked the source code for this method in following link Reference code for SolidBrush class

The code used in System.Drawing.SolidBrush.Clone method is

public override object Clone() 
        {
            IntPtr cloneBrush = IntPtr.Zero;

            int status = SafeNativeMethods.Gdip.GdipCloneBrush(new HandleRef(this, this.NativeBrush), out cloneBrush);

            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status);

            // We intentionally lose the "immutable" bit.

            return new SolidBrush(cloneBrush);
        }

It is clear, that the Clone method may throw exception but I'm not able to identify when or why it will throw exception, since this code is not mine.

Does anyone know when or why exception will be thrown by this method ?

Edit:

Attached the image showing exception details

Exception Image

Also, this is not a system brush, because immutable property of the brush is false

Not a system brush

1

There are 1 best solutions below

2
On BEST ANSWER

You could determine if it is actually the Clone() that is throwing the exception or the disposing. If you try to dispose or change a SystemBrush, then an exception will occur:

SystemBrushes.Control.Dispose(); // ArgumentException: Changes cannot be made to Brush because permissions are not valid.

But cloning it and then disposing it works fine:

((Brush) SystemBrushes.Control.Clone()).Dispose(); // OK

So maybe just avoid Clone altogether if you think that is the problem, e.g:

    // instead of using clone, just make a new instance
    Brush myBrush = SystemBrushes.Control;
    if (myBrush is SolidBrush) {
        using (var nb = new SolidBrush(((SolidBrush) myBrush).Color)) {
            // ...
        }
    }