在WPF C#中将项目放入ListView的特定索引位置

3

我在WPF中有一个ListView,其中包含一些文件。用户可以将文件拖动到列表视图中,现在它们只会被追加到列表的末尾。是否可以将文件插入到用户放置它的位置?

3个回答

4

WPF并不是为这种方式设计的。虽然你可以强制将ListViewItem直接添加到ListView中,但它真正应该工作的方式是你有一些集合(ObservableCollection<FileInfo>会很好地工作),并将ListView的ItemsSource属性绑定到该集合。

那么答案很简单。你使用集合的Insert方法而不是Add方法,该方法需要一个索引。

至于找到鼠标事件发生在哪个ListViewItem上,你可以使用VisualTreeHelper.HitTest方法。


2

在我看来,当我使用模板项时,它有点棘手。我花了一点时间与它斗争。我分享一下我的用例,它适用于DraggableListBox。但我认为相同的解决方案适用于ListBox控件。

首先,我创建了一个依赖对象扩展,它能够为我提供ListItem元素:

public static class WpfDomHelper
{
    public static T FindParent<T>(this DependencyObject child) where T : DependencyObject
    {

        DependencyObject parentObject = VisualTreeHelper.GetParent(child);

        if (parentObject == null) return null;

        T parent = parentObject as T;
        if (parent != null)
            return parent;
        else
            return FindParent<T>(parentObject);
    }
}

然后我实现了拖放逻辑,根据目标列表框项的特定 Drop Y 位置插入(添加)项目:

    private void Grid_Drop(object sender, DragEventArgs e)
    {
        int dropIndex = -1; // default position directong to add() call

        // checking drop destination position
        Point pt = e.GetPosition((UIElement)sender);
        HitTestResult result = VisualTreeHelper.HitTest(this, pt);
        if (result != null && result.VisualHit != null)
        {
            // checking the object behin the drop position (Item type depend)
            var theOne = result.VisualHit.FindParent<Microsoft.TeamFoundation.Controls.WPF.DraggableListBoxItem>();

            // identifiing the position according bound view model (context of item)
            if (theOne != null)
            {
                //identifing the position of drop within the item
                var itemCenterPosY = theOne.ActualHeight / 2;
                var dropPosInItemPos = e.GetPosition(theOne); 

                // geting the index
                var itemIndex = tasksListBox.Items.IndexOf(theOne.Content);                    

                // decission if insert before or below
                if (dropPosInItemPos.Y > itemCenterPosY)
                {  // when drag is gropped in second half the item is inserted bellow
                    itemIndex = itemIndex + 1; 
                }
                dropIndex = itemIndex;
            }
        }

        .... here create the item .....

        if (dropIndex < 0)
             ViewModel.Items.Add(item);
        else
             ViewModel.Items.Insert(dropIndex, item);

        e.Handled = true;

    }

所以这个解决方案适用于我的模板DraggableListBoxView,我想同样的解决方案也适用于标准的ListBoxView。祝好运。


1

你可以做到这一点。虽然需要一些工作,但是它是可以完成的。有一些演示可供参考,这里是CodeProject上的一个。这个特别的演示是由被称为WPF大师的Josh Smith所制作。它可能不完全符合你的要求,但应该非常接近。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接