Пользовательский элемент управления ListView не будет рисовать при первом показе

Я создал собственный элемент управления 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...

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

2 ответа

Решение

Вы должны установить набор элементов управления, чтобы перерисовать себя при изменении размера. Так что добавьте этот код в конструктор вашего элемента управления:

this.ResizeRedraw = true;

Мои извинения: выполнение приведенных ниже действий сбросило мои обработчики событий, и проблема исчезла. Однако, как только я подключил их, я обнаружил, что обработчик события Resize, который я использовал для установки ColumnWidth, вызывал проблему. Почему установка ColumnWidth вызывает это, я не знаю.

Комментарий Арво Боуэна к этому ответу также исправил это для меня (.NET 4.8 Framework, VS2022). Чтобы быть ясным, не требуя this.ResizeRedraw = true;из ответа.

Итак, после долгих головных болей и времени я обнаружил, что у меня нет абсолютно ничего плохого в моем контроле. Именно ваш ответ заставил меня создать еще один элемент управления, такой же, как мой существующий, и протестировать его. К моему удивлению, это сработало отлично. Я просто скопировал свой существующий нерабочий элемент управления и вставил его в форму, а затем новый заработал! Иногда VS просто делает странные вещи... Каким-то образом мне удалось испортить объект создания элемента управления или что-то в этом роде..

Другие вопросы по тегам