0

如何实现GetListBoxItemIndex下面的函数来获取我点击的项目的索引?我尝试使用但VisualTreeHelper没有成功(意思是,VisualTreeHelper显然有效,但我没有通过树搜索获得任何结果......)

private void MyListBox_OnPreviewMouseDown(object sender, MouseButtonEventArgs e){
    var listBox = sender as ListBox;
    var src = e.OriginalSource as DependencyObject;
    if (src == null || listBox == null) return;

    var i = GetListBoxItemIndex(listBox,src);

    DragDrop.DoDragDrop(src, BoundCollection[i], DragDropEffects.Copy);
    // BoundCollection defined as:
    // ObservableCollection<SomeDataModelType> BoundCollection
}

请注意,在此状态下尚未选择任何内容,因为它是一个PreviewMouseDown事件

4

1 回答 1

3

以下代码将帮助您解决问题,步骤在评论中,

private void ListBox_OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    // you can check which mouse button, its state, or use the correct event.

    // get the element the mouse is currently over
    var uie = ListBox.InputHitTest(Mouse.GetPosition(this.ListBox));

    if (uie == null)
        return;

    // navigate to its ListBoxItem container
    var listBoxItem = FindParent<ListBoxItem>((FrameworkElement) uie);

    // in case the click was not over a listBoxItem
    if (listBoxItem == null)
         return;

    // here is the index
    int index = this.ListBox.ItemContainerGenerator.IndexFromContainer(listBoxItem);
    MessageBox.Show(index.ToString());
}

public static T FindParent<T>(FrameworkElement child) where T : DependencyObject
{
    T parent = null;
    var currentParent = VisualTreeHelper.GetParent(child);

    while (currentParent != null)
    {

       // check the current parent
       if (currentParent is T)
       {
          parent = (T)currentParent;
          break;
       }

       // find the next parent
       currentParent = VisualTreeHelper.GetParent(currentParent);
    }

    return parent;
}

更新

你想要的是你点击的数据项的索引。获得容器后,在通过 获取与其关联的数据项之前,您无法获得索引DataContext,并在绑定集合中查找其索引。ItemContainerGenerator已经为您做到了。

在您的代码中,您假设索引与绑定集合中的数据项的索引相同,这仅在关闭ListBoxItem时才成立。Virtualization如果它打开,则仅实例化可见区域中项目的容器。例如,如果您的绑定集合中有 1000 个数据项,并且您已经滚动到第 50 个数据项,那么现在,理论上,ListBoxItem索引 0 绑定到第 50 个数据项,这证明您的假设是错误的。

前面说了理论上,因为开启时在滚动区域的顶部和底部会创建一些隐藏的容器Virtualization,以便键盘导航正常工作。

于 2014-02-24T16:54:46.997 回答