在列表视图中获取鼠标光标下的项目

本文关键字:光标 项目 鼠标 获取 列表 视图 | 更新日期: 2023-09-27 18:36:58

这可能看起来像是这个问题或这个问题的重复。但我的问题是如何处理获得的ListViewItem

我已经像这样设置ListView绑定

<ListView ItemsSource="{Binding Data}" ...>

哪里

public ObservableCollection<Item> Data { ... }

我如何获得Item(从ListViewItem)?


我尝试使用 mvvm 并绑定与此类似的当前鼠标悬停项目。但后来我更加磕磕绊绊了:

<ListView>
    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <!-- this will not work -->
                    <Setter Property="{Binding MouseoveredItem, RelativeSource={RelativeSource AncestorType={x:Type ListView}}}" Value="{Binding RelativeSource={RelativeSource Self}}"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </ListView.ItemContainerStyle>
</ListView>

我的意图清楚吗?我如何获得老鼠呐喊Item


我不敢相信没有人这样做过。这是代码隐藏尝试(以说明我的问题):

private void ListView_MouseMove(object sender, MouseEventArgs e)
{
    var item = VisualTreeHelper.HitTest(listView, Mouse.GetPosition(listView)).VisualHit;
    // find ListViewItem (or null)
    while (item != null && !(item is ListViewItem))
        item = VisualTreeHelper.GetParent(item);
    if (item != null)
    {
        ... // item is ListViewItem, how to convert ListViewItem it to Item
    }
}

我可以找到ListViewItem,但我需要鼠标悬停Item的属性,这些属性显示为SubItems或隐藏。如何将ListViewItemItem的视觉视图)转换为Item(这是ListViewItem代表的)?

在列表视图中获取鼠标光标下的项目

当你得到"ListViewItem"时,它的属性"DataContext"将返回你的"Item"。

在下面的代码片段中,ListView对象绑定了一个ObservableCollection<IDataItem>集合,其中IDataItem是一个自定义接口并继承INotifyPropertyChanged

在 .xaml 中:

MouseMove="listView_OnMouseMove"

在 .xaml 中.cs:

private void listView_OnMouseMove(object sender, MouseEventArgs e)
{        
    if (!(e.Source is UIElement selectedObject))
        return;
    var mousePosition = e.GetPosition(selectedObject);
    var dataContextObject = listView.GetObjectAtPoint<ListViewItem>(mousePosition);
    if (!(dataContextObject is IDataItem dataItem))
        return;
    // Deal with the selectedObject under the mouse cursor here
}

// How to get Item under cursor in WPF ListView
// https://www.py4u.net/discuss/1453642 - Answer #2
public static object GetObjectAtPoint<ItemContainer>(this ItemsControl control, Point p) 
    where ItemContainer : DependencyObject
{
    // ItemContainer - can be ListViewItem, or TreeViewItem and so on(depends on control)
    var obj = control.GetContainerAtPoint<ItemContainer>(p);
    if (obj == null)
        return null;
    return control.ItemContainerGenerator.ItemFromContainer(obj);
}
private static ItemContainer GetContainerAtPoint<ItemContainer>(this ItemsControl control, Point p) 
    where ItemContainer : DependencyObject
{
    var result = VisualTreeHelper.HitTest(control, p);
    var obj = result.VisualHit;
    while (VisualTreeHelper.GetParent(obj) != null && !(obj is ItemContainer))
    {
        obj = VisualTreeHelper.GetParent(obj);
    }
    // Will return null if not found
    return obj as ItemContainer;
}

在视图模型中使用它:

public ObservableCollection<Item> Data { ... }
public Item SelectedData { get; set; }

在你的视野中

<ListView ItemsSource="{Binding Data}" SelectedItem="{Binding SelectedData}" ...>

当所选内容更改时,"所选数据"属性也会更改。