views:

25

answers:

2

Hello everybody!

I have an odd problem with an enhanced WinForms ComboBox I wrote in C#. The box shows a list of colors with the color itself and the name of the color and is set to ComboBoxStyle.DropDownList, double buffering and DrawMode.OwnerDrawFixed. The items are drawn when the DrawItem-event is raised.

If I open the DropDown menu and scroll with the mouse wheel the behaviour and look and feel is alright. If I use the scrollbar thumb with the left mouse button the text in the panel gets all smudgy. Only if I hover over the shown items again the items will be redrawn correctly.

http://i.imgur.com/F99Zu.png

Help is much appreciated!

Michael

Edit: Code of the drawing method:

    private void OnDrawItem(object sender, DrawItemEventArgs e)
    {
        if (e.Index == -1)
        {
            return;
        }

        e.DrawBackground();

        Graphics grfx = e.Graphics;
        grfx.FillRectangle(mWhiteBrush, e.Bounds);

        ColorInfo colorInfo = (ColorInfo)Items[e.Index];
        Color brushColor = colorInfo.Color;

        using (SolidBrush brush = new SolidBrush(brushColor))
        {
            Rectangle rectangleColor = e.Bounds;
            Rectangle rectangleText = e.Bounds;

            rectangleColor.Width = rectangleColor.Height;
            rectangleText.X += rectangleColor.Width;
            rectangleText.Width -= rectangleColor.Width;

            grfx.FillRectangle(brush, rectangleColor);
            grfx.DrawString(colorInfo.Name, e.Font, mBlackBrush, rectangleText);
        }    
    }
+1  A: 

Without seeing the code, from your description, it sounds like there is a bug in your drawing code. One thing that I've seen in the past is that DrawItemEventArgs.State property of the event args can casue issues. It requires careful checking since it is a flag enum where multiple states can be set simultaneously.

Post the drawing / measuring code for more insight.

Also I assume you've double buffered this control, right?

For a quick fix try setting this:

grfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;

While a more robust solution is to handle the double buffering yourself in code as follows:

    private void comboBox1_DrawItem(object sender, DrawItemEventArgs e)
    {    
        if (e.Index == -1)
        {
            return;
        }

        using (Bitmap drawbuffer = new Bitmap(e.Bounds.Width, e.Bounds.Height))
        {
            using (Graphics grfx = Graphics.FromImage(drawbuffer))
            {
                grfx.FillRectangle(mWhiteBrush, 0, 0, e.Bounds.Width, e.Bounds.Height);

                ColorInfo colorInfo = (ColorInfo)Items[e.Index];
                Color brushColor = colorInfo.Color;

                using (SolidBrush brush = new SolidBrush(brushColor))
                {
                    Rectangle rectangleColor = new Rectangle();
                    Rectangle rectangleText = new Rectangle();

                    rectangleColor.Height = rectangleColor.Width = e.Bounds.Height;
                    rectangleText.X += rectangleColor.Width;
                    rectangleText.Width = e.Bounds.Width - e.Bounds.Height;

                    grfx.FillRectangle(brush, rectangleColor);
                    grfx.DrawString(colorInfo.Name, e.Font, mBlackBrush, rectangleText);
                }

                e.Graphics.DrawImageUnscaled(drawbuffer, e.Bounds);
            }
        }
    }
ach
Code of the drawning method is inserted. Yes, I use double buffering.
Mil
Added a quick fix that will solve the blurr...
ach
Thank you very much!
Mil
A: 

Well, redraw the background THEN text every time. Since you doublebuffer, you won't have flickering or any other problem.

Daniel Mošmondor