Как получить правильный ListViewItem под курсором мыши? - PullRequest
0 голосов
/ 10 марта 2019

Проблема с методом ListView.GetItemAt показана на снимке экрана ниже.

Код дизайнера

this.listView1 = new System.Windows.Forms.ListView();
this.SuspendLayout();
// 
// listView1
// 
this.listView1.Dock = System.Windows.Forms.DockStyle.Fill;
this.listView1.Location = new System.Drawing.Point(0, 0);
this.listView1.Name = "listView1";
this.listView1.Size = new System.Drawing.Size(717, 511);
this.listView1.TabIndex = 0;
this.listView1.UseCompatibleStateImageBehavior = false;
// 
// Form1
// 
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(717, 511);
this.Controls.Add(this.listView1);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);

Код позади

public Form1()
{
    InitializeComponent();
}

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 <= 10; ++i)
    {
        listView1.Items.Add($"item {i}", 0);
    }
}

private void ListView1_MouseMove(object sender, MouseEventArgs e)
{
    ListViewItem item = listView1.GetItemAt(e.X, e.Y);

    if (LastHoveredItem != null)
    {
        ListViewItem item2 = LastHoveredItem;
        LastHoveredItem = null;
        listView1.Invalidate(item2.Bounds);
    }

    if (item != null)
    {
        LastHoveredItem = item;
        listView1.Invalidate(item.Bounds);
    }
    else
    {
        LastHoveredItem = null;
    }
}

private void ListView1_DrawItem(object sender, DrawListViewItemEventArgs e)
{
    if (LastHoveredItem == e.Item)
    {
        e.Graphics.FillRectangle(Brushes.Yellow, e.Item.Bounds);
    }
    else
    {
        e.Graphics.FillRectangle(Brushes.Green, e.Item.Bounds);
    }
}

internal ListViewItem LastHoveredItem = null;

Снимок экрана

Прямоугольник под курсором мыши должен быть желтым, но он зелёный, как и другие, которые не зависли.

screenshot

Ответы [ 2 ]

1 голос
/ 10 марта 2019

ListView.GetItemAt получает элемент, если метка или прямоугольник значка содержит точку. Это не то, что вы ищете. Вам необходимо проверить весь товар.

Вы можете использовать любой из следующих методов:

Пример. Обнаружение горячего элемента в DrawItem

private void listView1_DrawItem(object sender, DrawListViewItemEventArgs e)
{
    //...
    var p = listView1.PointToClient(Cursor.Position);
    if (e.Item.GetBounds(ItemBoundsPortion.Entire).Contains(p))
    {
        //e.Item is Hot
    }
    else
    {
        //e.Item is Normal
    }
    //...
}
0 голосов
/ 12 марта 2019

Почему вы не можете использовать свойство listView1.FocusedItem

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...