覆盖ListBox的DrawItem - 未选中的项目不重绘 [英] Overriding DrawItem for ListBox - unselected items are not redrawn

查看:586
本文介绍了覆盖ListBox的DrawItem - 未选中的项目不重绘的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个C#桌面应用程序。我的 ListBox的 DrawStyle 属性设置为 OwnerDrawFixed

This is a C# desktop application. The DrawStyle property of my ListBox is set to OwnerDrawFixed.

问题:我重写DRAWITEM在不同的字体绘制文本,和它的作品。但是当我开始调整在运行时的形式,所选择的项目是正确绘制的,但他们的休息都没有重绘,导致文本寻找未选定项目已损坏。

The problem: I override DrawItem to draw text in different fonts, and it works. But when I start resizing the form at the runtime, the selected item is drawn correctly, but the rest of them are not redrawn, causing text looking corrupt for unselected items.

这里是我的代码:

private void listDevices_DrawItem(object sender, DrawItemEventArgs e)
{
    e.DrawBackground();

    string textDevice = ((ListBox)sender).Items[e.Index].ToString();

    e.Graphics.DrawString(textDevice,
        new Font("Ariel", 15, FontStyle.Bold), new SolidBrush(Color.Black), 
        e.Bounds, StringFormat.GenericDefault);


    // Figure out where to draw IP
    StringFormat copy = new StringFormat(
        StringFormatFlags.NoWrap |
        StringFormatFlags.MeasureTrailingSpaces
    );
    copy.SetMeasurableCharacterRanges(new CharacterRange[] {new CharacterRange(0, textDevice.Length)});

    Region[] regions = e.Graphics.MeasureCharacterRanges(
        textDevice, new Font("Ariel", 15, FontStyle.Bold), e.Bounds, copy);

    int width = (int)(regions[0].GetBounds(e.Graphics).Width);
    Rectangle rect = e.Bounds;
    rect.X += width;
    rect.Width -= width;

    // draw IP
    e.Graphics.DrawString(" 255.255.255.255",
        new Font("Courier New", 10), new SolidBrush(Color.DarkBlue),
        rect, copy);

    e.DrawFocusRectangle();
}

listDevices.Items.Add("Device001");
listDevices.Items.Add("Device002");



此外,(选择一个)是正确绘制的项目闪烁的形式调整大小。没什么大不了的,但如果有人知道为什么.... TNX

Also, the item that is drawn correctly (the selected one) is flickering on form resizing. No biggie, but if anyone know why.... tnx

推荐答案

将下面的代码在Resize事件:

Put the following code in the Resize event:

private void listDevices_Resize(object sender, EventArgs e) {
    listDevices.Invalidate();
}

这应该引起所有重绘。

要停止闪烁,则需要双缓冲。

To stop the flickering, you need double buffering.

要做到这一点,做一个新的类,从Control派生,并把在以下构造器:

To do this, make a new class, derived from ListBox, and put the following in the constructor:

this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);



或者只是粘贴到代码文件这样的:

Or just paste this into a code file:

using System.Windows.Forms;

namespace Whatever {
    public class DBListBox : ListBox {
        public DBListBox(): base() {
            this.DoubleBuffered = true;
            // OR
            // this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        }
    }
}



替换什么与命名空间项目使用,或使之更有用的东西。编译后,你应该能够添加在窗体设计器DBListBox。

Replace "Whatever" with the namespace your project uses, or make it something more useful. AFter compiling, you should be able to add a DBListBox in the form designer.

这篇关于覆盖ListBox的DrawItem - 未选中的项目不重绘的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆