这是一个C#桌面应用程序。该 DrawStyle 我的财产 ListBox 被设置为 OwnerDrawFixed.

问题出在哪里: 我复盖DrawItem以绘制不同字体的文本,并且它有效。但是,当我在运行时开始调整表单大小时,选定的项目被正确绘制,但其余的项目没有重新绘制,导致文本寻找未选择的项目。

这是我的代码:

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

此外,正确绘制的项目(选定的项目)在调整表单大小时闪烁。没什么大不了的,但如果有人知道为什么。...n.tnx

有帮助吗?

解决方案

将以下代码放入Resize事件中:

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

这应该会导致所有内容都被重绘。

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

为此,创建一个从ListBox派生的新类,并将以下内容放在构造函数中:

this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);

或者只是将其粘贴到代码文件中:

using System.Windows.Forms;

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

将"Whatever"替换为您的项目使用的命名空间,或者使其更有用。编译后,您应该可以在表单设计器中添加一个DBListBox。

其他提示

我责备这个问题。代码中有几个错误,字体名称为"Arial",您不应该调整rect。宽度,您忘记在字体,画笔和区域上调用Dispose()。但他们没有解释这种行为。剪切区域有问题,阻止文本正确更新。我没有看到发生在哪里,图形对象状态没问题。

图形。DrawString()是一个非常麻烦的方法,你真的应该避免它。所有Windows窗体控件(包括ListBox)都使用TextRenderer。DrawText()。这解决了我使用它时的问题。我知道测量更困难,你可以通过以固定偏移量显示IP地址来解决这个问题。看起来也更好,他们会这样排成一列。

它闪烁,因为你使用E.DrawBackground()。这会擦除现有的文本,您可以将文本重新绘制在其上。我不认为双缓冲会解决这个问题,你必须绘制整个项目,这样你就不必绘制背景。棘手的是,如果您无法获得大字体文本的确切大小,解决方法是首先绘制成位图。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top