C# 如何避免滚动时在自定义组合框下拉面板中重叠字符串?

C# 如何避免滚动时在自定义组合框下拉面板中重叠字符串?,c#,winforms,combobox,C#,Winforms,Combobox,我用C#编写的增强WinForms组合框有一个奇怪的问题。该框显示颜色列表以及颜色本身和颜色名称,并设置为ComboBoxStyle.DropDownList、double buffering和DrawMode.OwnerDrawFixed。在引发DrawItem事件时绘制项目 如果我打开下拉菜单并用鼠标滚轮滚动,行为和外观都很好。 如果我使用滚动条拇指和鼠标左键,面板中的文本会变得非常模糊。仅当我再次将鼠标悬停在显示的项目上时,项目才会正确地重新绘制 非常感谢您的帮助 迈克尔 编辑:绘图方法

我用C#编写的增强WinForms组合框有一个奇怪的问题。该框显示颜色列表以及颜色本身和颜色名称,并设置为ComboBoxStyle.DropDownList、double buffering和DrawMode.OwnerDrawFixed。在引发DrawItem事件时绘制项目

如果我打开下拉菜单并用鼠标滚轮滚动,行为和外观都很好。 如果我使用滚动条拇指和鼠标左键,面板中的文本会变得非常模糊。仅当我再次将鼠标悬停在显示的项目上时,项目才会正确地重新绘制

非常感谢您的帮助

迈克尔

编辑:绘图方法代码:

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

在没有看到代码的情况下,根据您的描述,您的图形代码中似乎存在错误。我在过去看到的一件事是,事件args的DrawItemEventArgs.State属性可以引发问题。它需要仔细检查,因为它是一个可以同时设置多个状态的标志枚举

张贴图纸/测量代码以了解更多信息

我还假设你对这个控件进行了双缓冲,对吗

要快速修复问题,请尝试设置此选项:

grfx.textrendinghint=System.Drawing.Text.textrendinghint.AntiAliasGridFit

而更健壮的解决方案是自己在代码中处理双缓冲,如下所示:

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

在没有看到代码的情况下,根据您的描述,您的图形代码中似乎存在错误。我在过去看到的一件事是,事件args的DrawItemEventArgs.State属性可以引发问题。它需要仔细检查,因为它是一个可以同时设置多个状态的标志枚举

张贴图纸/测量代码以了解更多信息

我还假设你对这个控件进行了双缓冲,对吗

要快速修复问题,请尝试设置此选项:

grfx.textrendinghint=System.Drawing.Text.textrendinghint.AntiAliasGridFit

而更健壮的解决方案是自己在代码中处理双缓冲,如下所示:

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

嗯,每次都要重新绘制背景,然后是文本。由于您使用了双缓冲区,因此不会出现闪烁或任何其他问题。

好吧,每次都要重新绘制背景,然后是文本。由于使用了双缓冲区,所以不会出现闪烁或任何其他问题。

插入了绘图方法的代码。是的,我使用双缓冲。插入了绘图方法的代码。是的,我使用双缓冲。