4

I have a listview that displays files from a directory.
The user can drag each item in the listview to a folder/ the desktop and the associated file is copied there.
This works fine. The problem is- I want to do so for multiple items- so the user can select multiple listviewitems and drag and copy them together. The ListView is set to SelectedMode=Multiple- but it doesn't copy all of the selected items. Here's my code:

    private void FileView_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        this.start = e.GetPosition(null);
    }

    private void FileView_MouseMove(object sender, MouseEventArgs e)
    {
        Point mpos = e.GetPosition(null);
        Vector diff = this.start - mpos;

        if (e.LeftButton == MouseButtonState.Pressed &&
            Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance &&
            Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)
        {
            if (this.FileView.SelectedItems.Count == 0)
            {
                return;
            }

            // right about here you get the file urls of the selected items.  
            // should be quite easy, if not, ask.  
            string[] files = new String[1];
            files[0] = "C:\\Users\\MyName\\Music\\My playlist\\" + FileView.SelectedValue.ToString();
            string dataFormat = DataFormats.FileDrop;
            DataObject dataObject = new DataObject(dataFormat, files);
            DragDrop.DoDragDrop(this.FileView, dataObject, DragDropEffects.Copy);
        } 
    }

Thanks!

3 Answers 3

8
 private List<object> _selItems = new List<object>();
    private void FileView_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        this._start = e.GetPosition(null);
        _selItems.Clear();
        _selItems.AddRange(FileView.SelectedItems.Cast<object>());

    }

restore on MouseMove

foreach (object selItem in _selItems)
            {
                if (!FileView.SelectedItems.Contains(selItem))
                    FileView.SelectedItems.Add(selItem);
            }
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for this, it's exactly what I was needing. The selection was changing to the one item under the cursor before I could grab all the selected items.
5

The problem here is that you are using SelectedValue for a multiselect, so you get one file. What you want is something more like this:

private void FileView_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    this.start = e.GetPosition(null);
}

private void FileView_MouseMove(object sender, MouseEventArgs e)
{
    Point mpos = e.GetPosition(null);
    Vector diff = this.start - mpos;

    if (e.LeftButton == MouseButtonState.Pressed &&
        (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
         Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)
    )
    {
        if (this.FileView.SelectedItems.Count == 0)
            return;

        // right about here you get the file urls of the selected items.  
        // should be quite easy, if not, ask.  
        string[] files = new String[FileView.SelectedItems.Count];
        int ix = 0;
        foreach (object nextSel in FileView.SelectedItems)
        {
            files[ix] = "C:\\Users\\MyName\\Music\\My playlist\\" + nextSel.ToString();
            ++ix;
        }
        string dataFormat = DataFormats.FileDrop;
        DataObject dataObject = new DataObject(dataFormat, files);
        DragDrop.DoDragDrop(this.FileView, dataObject, DragDropEffects.Copy);
    } 
}

Comments

3

I'd like to point out an small error in the code

    Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance &&
    Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)

should be

    Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
    Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)

Otherwise a straight Horizontal or Vertical will do nothing. Chances of that happening are small, but still..

1 Comment

... or use the Vector's Length property instead

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.