Ниже приведен код. Я видел, что событие MouseMove не всегда срабатывает, особенно когда мышь перемещается очень быстро, и из-за этого два элемента могут быть помечены как наведенные одновременно, поэтому теперь я использую переменную для удержания последнего элемента наведения, но Проблема в том, что слишком много перерисовок. Я также видел, что DrawListViewItemEventArgs.State свойство просто ShowKeyboardCues
, когда оно также должно содержать Hot
.
private void Form1_Load(object sender, EventArgs e)
{
listView1.OwnerDraw = true;
listView1.View = View.LargeIcon;
listView1.DrawItem += ListView1_DrawItem;
listView1.MouseMove += ListView1_MouseMove;
for (int i = 1; i <= 6; ++i)
{
listView1.Items.Add($"item {i}", 0);
}
}
private void ListView1_MouseMove(object sender, MouseEventArgs e)
{
ListViewItem item = listView1.GetItemAt(e.X, e.Y);
if (item != null)
{
if (LastHoveredItem != null && LastHoveredItem.Index == item.Index)
{
return;
}
listView1.RedrawItems(item.Index, item.Index, false);
}
}
internal ListViewItem LastHoveredItem = null;
private void ListView1_DrawItem(object sender, DrawListViewItemEventArgs e)
{
bool hot = e.Item.Bounds.Contains(listView1.PointToClient(Cursor.Position));
if (LastHoveredItem != null)
{
listView1.RedrawItems(LastHoveredItem.Index, LastHoveredItem.Index, false);
}
if (hot)
{
LastHoveredItem = e.Item;
e.Graphics.FillRectangle(Brushes.Green, e.Bounds);
}
else
{
LastHoveredItem = null;
}
e.DrawText();
}