Как выяснилось позже, при добавлении элемента в ListView, он мерцанёт в любом случае, хоть забуферизируйся.
А при частом добавлении это особенно заметно.
В том проекте элементов в списке всегда меньше 20 штук и добавляются они только при загрузке программы или по кнопке раз в полгода. Видимо, по-этому мерцание незаметно.
Сейчас я начал новый проект и опять сразу наткнулся на этот косяк с мерцанием. Вот обновлённый код:
private void listViewRooms_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
{
try
{
using (Bitmap bitmap = new Bitmap(e.Bounds.Width, e.Bounds.Height))
{
using (Graphics buffer = Graphics.FromImage(bitmap))
{
using (StringFormat sf = new StringFormat())
{
ListView listView = sender as ListView;
sf.FormatFlags = StringFormatFlags.NoWrap;
sf.LineAlignment = StringAlignment.Center;
switch (e.Header.TextAlign)
{
case HorizontalAlignment.Center:
sf.Alignment = StringAlignment.Center;
break;
case HorizontalAlignment.Right:
sf.Alignment = StringAlignment.Far;
break;
}
bool selected = listView.SelectedIndices.Count > 0 && listView.SelectedIndices[0] == e.ItemIndex;
Room room = listView.Items[e.ItemIndex].Tag as Room;
GetColor(room, out Color colorBackground, out Color colorForeground);
using (Brush brushBackground = new SolidBrush(colorBackground))
{
using (Brush brushText = new SolidBrush(colorForeground))
{
Rectangle r = new Rectangle(0, 0, e.Bounds.Width, e.Bounds.Height);
buffer.FillRectangle(brushBackground, r);
if (e.ColumnIndex == 0)
{
r = r.Move(14, 0);
if (selected)
{
int squareSize = e.Bounds.Height - 8;
Rectangle square = new Rectangle(2, 4, squareSize, squareSize);
buffer.FillRectangle(SystemBrushes.Highlight, square);
}
}
buffer.DrawString(e.SubItem.Text, listView.Font, brushText, r, sf);
if (selected)
{
r.Height -= 1;
buffer.DrawLine(Pens.Blue, 0, 0, r.Right, 0);
buffer.DrawLine(Pens.Blue, 0, r.Bottom, r.Right, r.Bottom);
}
e.Graphics.DrawImage(bitmap, e.Bounds.X, e.Bounds.Y);
}
}
}
}
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.StackTrace);
}
}
Мерцает тем цветом, который установлен у ListView в свойстве BackColor
. Особенно сильно это заметно если перемещаться по списку стрелочками вверх
и вниз
.
Как будто он фон отрисовывает раньше, чем элементы. Но как это пофиксить - не понятно И зачем он вообще заливает пространство под элементами Оно же и так будет сразу перерисовано самими же элементами.