C# 使用itemssource时找出列表视图中鼠标位于哪个项目上

C# 使用itemssource时找出列表视图中鼠标位于哪个项目上,c#,wpf,C#,Wpf,问题: 使用源项填充列表视图时,这些项不再是ListViewItem,而是类/结构或用作.ItemsSource的任何对象,这意味着我不能在PreviewMouseMove事件中使用“.IsMouseOver”属性 我试过什么 将ListViewItem强制转换为ListViewItem,然后在其上调用.IsMouseOver不会在任何内容下划下划线,但在运行时,当您将鼠标放在列表视图上并说“无法将类名强制转换为ListViewItem”时会崩溃 我试着让我的类从IInputElement公共类

问题:

使用源项填充列表视图时,这些项不再是ListViewItem,而是类/结构或用作.ItemsSource的任何对象,这意味着我不能在PreviewMouseMove事件中使用“.IsMouseOver”属性

我试过什么

将ListViewItem强制转换为ListViewItem,然后在其上调用.IsMouseOver不会在任何内容下划下划线,但在运行时,当您将鼠标放在列表视图上并说“无法将类名强制转换为ListViewItem”时会崩溃 我试着让我的类从IInputElement公共类继承名称:IInputElement Dunno如果可能或不可行,说它找不到它,我对c有点陌生,所以我不知道这到底是怎么回事,我假设它必须是一个可见的元素,你才能看到。我在上面。
我试着让我的类像public ClassName:ListViewItem那样从ListViewItem继承,这很有效!但是ListViewItem不包含.IsMouseOver属性,而且它仍然不允许我将类强制转换为ListViewItem而不崩溃实际上,即使绑定ListView项资源,您的可视树中仍然会有ListViewItems。这就是WPF所称的项目容器,例如ListBoxItem

ListView上有一个名为ItemContainerGenerator的属性。这将返回一个ItemContainerGenerator对象,该对象具有一个名为ContainerFromItem的方法,该方法将返回与您的对象关联的ListViewItem


然后,由于项目容器生成器,您可以在检索到的容器上使用IsMouseOver。

实际上,即使您绑定了ListView项目资源,您的可视树中仍然会有ListViewItems。这就是WPF所称的项目容器,例如ListBoxItem

ListView上有一个名为ItemContainerGenerator的属性。这将返回一个ItemContainerGenerator对象,该对象具有一个名为ContainerFromItem的方法,该方法将返回与您的对象关联的ListViewItem


然后,由于项目容器生成器,您可以在检索的容器上使用IsMouseOver。

您仍然应该将控件绑定到逻辑对象。虽然SelectedItem属性不是ListViewItem,但可视化树仍将包含一个。将VisualTreeHelper和HitTest用于鼠标悬停的项目。获得该项后,请检查绑定项的DataContext属性

下面是一些代码:

private ListViewItem FindListViewItem(DragEventArgs e)
{
    var visualHitTest = VisualTreeHelper.HitTest(_listView, e.GetPosition(_listView)).VisualHit;

    ListViewItem listViewItem = null;

    while (visualHitTest != null)
    {
        if (visualHitTest is ListViewItem)
        {
            listViewItem = visualHitTest as ListViewItem;

            break;
        }
        else if (visualHitTest == _listView)
        {
            Console.WriteLine("Found ListView instance");
            return null;
        }

        visualHitTest = VisualTreeHelper.GetParent(visualHitTest);
    }

    return listViewItem;
}

另一个选项是设置ItemsContainerStyle的样式,以便按照您想要的方式处理鼠标。

您仍然应该将控件绑定到逻辑对象。虽然SelectedItem属性不是ListViewItem,但可视化树仍将包含一个。将VisualTreeHelper和HitTest用于鼠标悬停的项目。获得该项后,请检查绑定项的DataContext属性

下面是一些代码:

private ListViewItem FindListViewItem(DragEventArgs e)
{
    var visualHitTest = VisualTreeHelper.HitTest(_listView, e.GetPosition(_listView)).VisualHit;

    ListViewItem listViewItem = null;

    while (visualHitTest != null)
    {
        if (visualHitTest is ListViewItem)
        {
            listViewItem = visualHitTest as ListViewItem;

            break;
        }
        else if (visualHitTest == _listView)
        {
            Console.WriteLine("Found ListView instance");
            return null;
        }

        visualHitTest = VisualTreeHelper.GetParent(visualHitTest);
    }

    return listViewItem;
}

另一个选项是设置项目的样式ContainerStyle,以按照您想要的方式处理鼠标。

正在实现这一点,如果我让它工作,我会选择itOk,它有点工作,但在我获得列表视图项目后,我如何将其强制转换到我的类中?因为classnamelistviewitem说我无法将listview项转换为classname….@JustinKirk一旦拥有了该项,请检查绑定项的DataContext属性。正在实现该项,如果我让它工作,我会选择itOk,它可以工作,但在我获得列表视图项后,我如何将其强制转换到我的类?因为classnamelistviewitem说我无法将listview项转换为classname…@JustinKirk一旦你拥有了该项,请检查绑定项的DataContext属性。感谢你的建议,你上面的人给出了相同的建议+代码,所以我选择了他的答案>:嘿,只要你解决了问题,我为你感到高兴!干杯谢谢你的建议,你上面的人给出了相同的建议+代码,所以我选择了他的答案>:嘿,只要你解决了你的问题,我为你感到高兴!干杯