I have a ListView in a WPF application where I want to add a Grid with some Buttons to each ListViewItem by way of an custom Adorner. The adorner is currently being added when the MouseEnter event fires for the ListViewItem, e.g. when I move the mouse into the ListViewItem, and removed when the MouseLeave event happens on the ListViewItem. This causes a loop, however, of MouseEnter/MouseLeave events because when the Adorner is added it causes the Adorner to become the focus of the mouse and not the ListViewItem. In other words, as soon as the Adorner is added, it is immediately removed because of the MouseLeave event that is fired from the ListViewItem.
I have seen some suggestions about adding the "IsHitTestVisible = false" attribute to the Adorner, but I need to be able capture click events on the buttons in the Adorner.
Abbreviated Adorner Class
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 { }
Main window functions for 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;
}
}
What happens is just a continuous loop where the adorner flickers on and off but I would like to just have it appear when the mouse is over the ListViewItem and hidden when not on the ListViewItem.