Как обрабатывать события MouseEnter и MouseLeave в WPF, если Adorner отображается прямо поверх элемента управления WPF? - PullRequest
0 голосов
/ 17 июня 2019

У меня есть ListView в приложении WPF, где я хочу добавить Grid с несколькими кнопками к каждому ListViewItem посредством пользовательского Adorner. Adorner в настоящее время добавляется, когда вызывается событие MouseEnter для ListViewItem, например, когда я перемещаю мышь в ListViewItem и удаляю, когда происходит событие MouseLeave в ListViewItem. Однако это вызывает цикл событий MouseEnter / MouseLeave, потому что когда Adorner добавляется, это заставляет Adorner становиться фокусом мыши, а не ListViewItem. Другими словами, как только Adorner добавлен, он немедленно удаляется из-за события MouseLeave, которое вызывается из ListViewItem.

Я видел несколько предложений по добавлению атрибута «IsHitTestVisible = false» в Adorner, но мне нужно иметь возможность фиксировать события нажатия на кнопки в Adorner.

Сокращенный класс Adorner


private readonly VisualCollection visualChildren;
private Grid adornerGrid;

public ListViewItemOptionsAdorner(UIElement adornedElement): base(adornedElement)
{
    visualChildren = new VisualCollection(this);
    adornerGrid = new Grid();
    Button editButton = new Button();
    Button deleteButton = new Button();

    adornerGrid.Children.Add(editButton);
    adornerGrid.Children.Add(deleteButton);

    visualChildren.Add(adornerGrid);

    MouseEnter += ListViewItemOptionsAdorner_MouseEnter;
    MouseLeave += ListViewItemOptionsAdorner_MouseLeave;

}

private void ListViewItemOptionsAdorner_MouseEnter { }

private void ListViewItemOptionsAdorner_MouseLeave { }

Функции главного окна для ListView

private void List_MouseEnter(object sender, MouseEventArgs e)
{
    ListViewItem listItem = sender as ListViewItem;
    AdornerLayer myAdornerLayer = AdornerLayer.GetAdornerLayer(listItem);
    myAdornerLayer.Add(new ListViewItemOptionsAdorner(listItem));

    e.Handled = true;
}

private void List_MouseLeave(object sender, MouseEventArgs e)
{
    ListViewItem listItem = sender as ListViewItem;

    if (!listItem.IsMouseOver)
    {
        AdornerLayer myAdornerLayer = AdornerLayer.GetAdornerLayer(listItem);
        Adorner[] adorners = myAdornerLayer.GetAdorners(listItem);
        for (int i = 0; adorners.Length; i++)
            myAdornerLayer.Remove(adorners[i]);
        e.Hanlded = true;
    }
}

То, что происходит, - это просто непрерывный цикл, когда рекламщик мерцает и выключается, но я бы хотел, чтобы он появлялся, когда указатель мыши находится над ListViewItem, и скрывался, когда его нет на ListViewItem.

...