Не знаю, поможет ли это вам полностью, но я добавлю несколько заметок:
Следует иметь в виду, что DrawSubItem
также нарисует первый элемент, и, вероятно, именно отсюда вы получаете double-rendered
взгляд.
Некоторые вещи, которые нужно попробовать (без учета скорости):
private void listView1_DrawItem(object sender, DrawListViewItemEventArgs e) {
e.DrawBackground();
if ((e.State & ListViewItemStates.Selected) == ListViewItemStates.Selected) {
Rectangle r = new Rectangle(e.Bounds.Left + 4, e.Bounds.Top, TextRenderer.MeasureText(e.Item.Text, e.Item.Font).Width, e.Bounds.Height);
e.Graphics.FillRectangle(SystemBrushes.Highlight, r);
e.Item.ForeColor = SystemColors.HighlightText;
} else {
e.Item.ForeColor = SystemColors.WindowText;
}
e.DrawText();
e.DrawFocusRectangle();
}
Для вашей подпрограммы DrawSubItem убедитесь, что вы не рисуете в первом столбце, и я добавил подпрограмму DrawBackground()
. Я добавил немного отсечения в прямоугольник выделения, чтобы он не рисовал вне параметров столбца.
private void listView1_DrawSubItem(object sender, DrawListViewSubItemEventArgs e) {
if (e.ColumnIndex > 0) {
e.DrawBackground();
string searchTerm = "Term";
int index = e.SubItem.Text.IndexOf(searchTerm);
if (index >= 0) {
string sBefore = e.SubItem.Text.Substring(0, index);
Size bounds = new Size(e.Bounds.Width, e.Bounds.Height);
Size s1 = TextRenderer.MeasureText(e.Graphics, sBefore, this.Font, bounds);
Size s2 = TextRenderer.MeasureText(e.Graphics, searchTerm, this.Font, bounds);
Rectangle rect = new Rectangle(e.Bounds.X + s1.Width, e.Bounds.Y, s2.Width, e.Bounds.Height);
e.Graphics.SetClip(e.Bounds);
e.Graphics.FillRectangle(new SolidBrush(Color.Yellow), rect);
e.Graphics.ResetClip();
}
e.DrawText();
}
}
В общем, владелец, рисующий элемент управления ListView, радушен в мире боли. Вы больше не рисуете в визуальных стилях, вам придется делать это и самим. Тьфу.