0

Hi I have a c# usercontrol that I override OnPaint method.

In my OnPaint Method I have the following code:

// Draw the new button. 
protected override void OnPaint(PaintEventArgs e) {
    Color btnColor = this.ButtonColor;
    if (!this.ButtonEnabled) {
        btnColor = Color.LightGray;
    }


    Bitmap GraphicsImage = new Bitmap(24, 24, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
    Graphics.FromImage(GraphicsImage).Clear(btnColor);

    Graphics graphics = e.Graphics;
    SolidBrush myBrush = new SolidBrush(btnColor);
    Pen myPen = new Pen(btnColor);
    // Draw the button in the form of a circle
    graphics.DrawEllipse(myPen, 0, 0, 40, 40);
    graphics.FillEllipse(myBrush, new Rectangle(0, 0, 40, 40));



    if (!DesignMode) {
        Image iconImg = null;

        switch (this.ButtonImage) {
            case CircleButtonImage.ArrowDown:
                iconImg = POS.Framework.Utility.Common.GetResourceImage("arrowdown_16.png");
                break;
            case CircleButtonImage.ArrowUp:
                iconImg = POS.Framework.Utility.Common.GetResourceImage("arrowup_16.png");
                break;
            case CircleButtonImage.Cross:
                iconImg = POS.Framework.Utility.Common.GetResourceImage("close_16.png");
                break;
            case CircleButtonImage.Plus:
                iconImg = POS.Framework.Utility.Common.GetResourceImage("plus_16.png");
                break;
        }


        graphics = Graphics.FromImage(GraphicsImage);
        graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
        graphics.DrawImage(iconImg, 5, 5);

        this.CreateGraphics().DrawImageUnscaled(GraphicsImage, new Point(7, 6));

    }


    myBrush.Dispose();
    myPen.Dispose();
}

This works well but in order to avoid flickering I added to my constructor:

 this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true);

Then the png image is not showing any more.

Without doublebufferd:

enter image description here

With doublebuffered:

enter image description here

Any clue on how to fix this. I want to avoid flickering but need the image to be rendered.

VAAA
  • 14,531
  • 28
  • 130
  • 253

1 Answers1

0

Don't use CreateGraphics. The Graphics object you need to use is passed as an argument to OnPaint, in the PaintEventArgs.

Additionaly, you really should clean up after yourself:

using (var graphics = Graphics.FromImage(GraphicsImage))
{
  graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
  graphics.DrawImage(iconImg, 5, 5);
}

GDI+ objects are quite a limited resource :) Apart from that, SmoothingMode has little use for what you're doing here - it really helps to at least read the documentation instead of just cargo-culting.

Luaan
  • 62,244
  • 7
  • 97
  • 116
  • I just commented the line: this.CreateGraphics().DrawImageUnscaled(GraphicsImage, new Point(7, 6)); But still the same problem – VAAA Mar 31 '16 at 17:07
  • @VAAA Why? That just prevents the image from drawing. Just use the `Graphics` object you're passed. – Luaan Mar 31 '16 at 17:08
  • I change the last part to this: using (var graphics1 = Graphics.FromImage(GraphicsImage)) { graphics1.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; graphics1.DrawImage(iconImg, 5, 5); graphics1.DrawImageUnscaled(GraphicsImage, new Point(7, 6)); } But the png image is not rendered. Btw appreciate so much your help. – VAAA Mar 31 '16 at 17:10
  • @VAAA You need to use the `Graphics` object passed to your `OnPaint` method, not a random `Graphics` object you find somewhere. – Luaan Mar 31 '16 at 17:12
  • I just update the question with the hole code under OnPaint, you will see that graphics = e.Graphics. – VAAA Mar 31 '16 at 17:16
  • @VAAA That's only true *before you replace it with another*. The `graphics = Graphics.FromImage(...)` replaces your graphics object with one created for the *input* image. – Luaan Mar 31 '16 at 17:52