自定义 ListView 控件在首次显示时不会绘制

Custom ListView control will not paint when first shown

我已经创建了一个自定义 ListView 控件来满足我的需要,但我遇到了一个问题,导致 ListView 在首次加载表单时不显示任何内容(不绘制任何内容,只是白色)。

如果我调整窗体大小或单击我的控件(任何强制在 ListView 上重绘的东西),它就会按预期显示。

附带说明一下,在我今天做了一个小改动并重新构建控件之前,它曾经工作得很好。我删除了我所做的所有更改并再次重建,但问题仍然存在。关于第一次加载表单时为什么不显示(绘制)的任何想法?

这是我用来在我的自定义 ListView 控件上进行自定义绘图的...

protected override void OnDrawItem(DrawListViewItemEventArgs e)
{
    Image image = e.Item.ImageList.Images[e.Item.ImageIndex];
    Size textSize = new Size((int)e.Graphics.MeasureString(e.Item.Text, e.Item.Font).Width, (int)e.Graphics.MeasureString(e.Item.Text, e.Item.Font).Height);

    //Get the area of the item to be painted
    Rectangle bounds = e.Bounds;
    bounds.X = 0;
    bounds.Width = this.Width;

    //Set the spacing on the list view items
    int hPadding = 0;
    int vPadding = 0;
    IntPtr padding = (IntPtr)(int)(((ushort)(hPadding + bounds.Width)) | (uint)((vPadding + bounds.Height) << 16));
    SendMessage(this.Handle, (uint)ListViewMessage.LVM_SETICONSPACING, IntPtr.Zero, padding);

    //Set the positions of the image and text
    int imageLeft = (bounds.Width / 2) - (image.Width / 2);
    int imageTop = bounds.Top + 3;
    int textLeft = (bounds.Width / 2) - (textSize.Width / 2);
    int textTop = imageTop + image.Height;
    Point imagePosition = new Point(imageLeft, imageTop);
    Point textPosition = new Point(textLeft, textTop);

    //Draw background
    using (Brush brush = new SolidBrush(e.Item.BackColor))
        e.Graphics.FillRectangle(brush, bounds);

    //Draw selected
    if (e.Item.Selected)
    {
        using (Brush brush = new SolidBrush(m_SelectedColor))
            e.Graphics.FillRectangle(brush, bounds);
    }

    //Draw image
    e.Graphics.DrawImage(image, imagePosition);

    //Draw text
    e.Graphics.DrawString(e.Item.Text, e.Item.Font, new SolidBrush(e.Item.ForeColor), textPosition);
}

我还在自定义控件的构造函数中设置了以下内容...

public MyListView()
{
    this.DoubleBuffered = true;
    this.OwnerDraw = true;
    this.View = View.LargeIcon;
    this.Cursor = Cursors.Hand;
    this.Scrollable = false;
}

我也继承了ListView class...

public class MyListView : ListView
{
    //All my source
}

您需要将控件设置为在调整大小时自行重绘。所以在你的控件的构造函数中添加这段代码:

this.ResizeRedraw = true;

抱歉: 执行以下操作重置我的事件处理程序,问题就消失了。但是,一旦我将它们连接起来,我发现我用来设置 ColumnWidth 的 Resize 事件处理程序导致了问题。为什么设置 ColumnWidth 会导致这个,我不知道。

Arvo Bowen 对此的评论 也为我修复了它(.NET 4.8 Framework,VS2022)。明确地说,不需要 this.ResizeRedraw = true; 的答案。

So after much headache and time I found that I had absolutely nothing wrong with my control. It was your answer that made me create another control just like my existing one and test it. To my surprise it worked great. I simply copied my existing non-working control and pasted it on the form and then new one worked! Sometimes VS just does weird things... Somehow I managed to muck up the control's creation object or something..