Перетащите элемент в определенный индекс в ListView в WPF C # - PullRequest
3 голосов
/ 26 мая 2010

У меня есть список файлов в ListView в WPF. Пользователи могут перетаскивать файлы в представление списка, и сейчас они просто добавляются в конец списка. Можно ли вставить файл в ListView там, где его уронил пользователь?

Ответы [ 3 ]

4 голосов
/ 26 мая 2010

WPF не предназначен для такого использования. Хотя вы можете просто добавить ListViewItem непосредственно к ListView, способ, которым он действительно должен работать, заключается в том, что у вас есть какая-то коллекция (ObservableCollection<FileInfo> будет работать хорошо) и привязать свойство ListSource ListView к этой коллекции.

Тогда ответ прост. Вместо метода Add используется метод Insert коллекции, которая принимает индекс.

Что касается нахождения ListViewItem, при котором произошло событие мыши, вы можете использовать метод VisualTreeHelper.HitTest .

2 голосов
/ 26 сентября 2017

С моей точки зрения, это немного сложно, когда я использовал шаблонный элемент. Я немного поборолся с этим. Я делюсь своим вариантом использования, который работает с 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);
    }
}

Затем я реализовал логику удаления, которая вставляет (добавляет) элемент в соответствии с конкретной позицией удаления 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;

    }

Так что это решение работает с моим шаблоном DraggableListBoxView, я полагаю, что это же решение должно работать со стандартным ListBoxView. Удачи

1 голос
/ 26 мая 2010

Вы можете сделать это. Требуется немного работы, но это может быть сделано. Там есть пара демонстраций, вот одна на CodeProject . Этот конкретный автор - мастер wpf, известный как Джош Смит. Это, вероятно, не совсем то, что вы ищете, но это должно быть чертовски близко.

...