Drop Item to specific index in ListView in WPF C #

I have a list of files in a ListView in WPF. Users can drag and drop files into the list view, and now they are simply added to the end of the list. Is it possible to insert a file into the ListView right where the user dumped it?

+3
source share
3 answers

WPF is not intended to be used in this way. Although you can force the ListViewItem to be added directly to the ListView, the way it really should work is that you have some kind of collection ( ObservableCollection<FileInfo>will work well) and bind the ListView ItemsSource property to this collection.

. Add Insert , .

, ListViewItem , VisualTreeHelper.HitTest.

+4

. , . , CodeProject. wpf, . , , , , .

+1

, , . . usecase, 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-, () Drop Y ListBoxItems:

    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;

    }

So this solution works with my DraggableListBoxView template, I believe that the same solution should work with the standard ListBoxView. Good luck

0
source

Source: https://habr.com/ru/post/1747121/


All Articles