0

I have ListView with ItemSource:

public ObservableCollection<MyObject> List;

And my ListView is full with several object.

Now i want to add the option to change my ListViewItems via darg so i found this solution: https://fxmax.wordpress.com/2010/10/05/wpf/

And after add the code inside my project i only have one problem that cause crash:

private void BeginDrag(MouseEventArgs e)
        {
            ListView listView = this.listView;
            ListViewItem listViewItem = FindAnchestor<ListViewItem>((DependencyObject)e.OriginalSource);

            if (listViewItem == null)
                return;

            // get the data for the ListViewItem
            MyObject name = (MyObject)listView.ItemContainerGenerator.ItemFromContainer(listViewItem);

            //setup the drag adorner.
            InitialiseAdorner(listViewItem);

            //add handles to update the adorner.
            listView.PreviewDragOver += listView_PreviewDragOver;
            listView.DragLeave += listView_DragLeave;
            listView.DragEnter += listView_DragEnter;

            DataObject data = new DataObject("myFormat", name);
            DragDropEffects de = DragDrop.DoDragDrop(this.listView, data, DragDropEffects.Move);

            //cleanup 
            listView.PreviewDragOver -= listView_PreviewDragOver;
            listView.DragLeave -= listView_DragLeave;
            listView.DragEnter -= listView_DragEnter;

            if (_adorner != null)
            {
                AdornerLayer.GetAdornerLayer(listView).Remove(_adorner);
                _adorner = null;
            }
        }

At this line:

DragDropEffects de = DragDrop.DoDragDrop(this.listView, data, DragDropEffects.Move);

System.InvalidOperationException: 'Operation is not valid while ItemsSource is in use. Access and modify elements with ItemsControl.ItemsSource instead.'

I can see that is because i am using ItemSource but dont know what to change.

Any suggestions ?

falukky
  • 1,099
  • 2
  • 14
  • 34
  • Please provide a MCVE when asking a question: https://stackoverflow.com/help/mcve – mm8 Jul 03 '18 at 09:15

1 Answers1

1

Starting from the sample code that you linked on the other site, I did some changes and was able to fix the solution to work with ItemsSource.

The changes done are as follows: - in MainWindow.xaml

            <ListView ItemsSource="{Binding List}"
              x:Name="listView"

- in MainWindow.xaml.cs

 private void ListViewDrop(object sender, DragEventArgs e)
    {
        if (e.Data.GetDataPresent("myFormat"))
        {
            MyObject name = e.Data.GetData("myFormat") as MyObject;
            ListViewItem listViewItem = FindAnchestor<ListViewItem>((DependencyObject)e.OriginalSource);
            ObservableCollection<MyObject> myArray = listView.ItemsSource as ObservableCollection<MyObject>;

            if (listViewItem != null && listViewItem.DataContext is MyObject)
            {
                MyObject dropLocation = (MyObject)listViewItem.DataContext;
                int index = myArray.IndexOf(dropLocation);

                if (index >= 0)
                {
                    myArray.Remove(name);
                    myArray.Insert(index, name);
                }
            }
            else
            {
                myArray.Remove(name);
                myArray.Add(name);
            }
        }
    }

...

private void BeginDrag(MouseEventArgs e)
    {
        ListView listView = this.listView;
        ListViewItem listViewItem =
            FindAnchestor<ListViewItem>((DependencyObject)e.OriginalSource);

        if (listViewItem == null)
            return;

        MyObject selectedItem = (MyObject)listViewItem.DataContext;

        //setup the drag adorner.
        InitialiseAdorner(listViewItem);

        //add handles to update the adorner.
        listView.PreviewDragOver += ListViewDragOver;
        listView.DragLeave += ListViewDragLeave;
        listView.DragEnter += ListViewDragEnter;

        DataObject data = new DataObject("myFormat", selectedItem);
        DragDropEffects de = DragDrop.DoDragDrop(this.listView, data, DragDropEffects.Move);

        //cleanup 
        listView.PreviewDragOver -= ListViewDragOver;
        listView.DragLeave -= ListViewDragLeave;
        listView.DragEnter -= ListViewDragEnter;

        if (_adorner != null)
        {
            AdornerLayer.GetAdornerLayer(listView).Remove(_adorner);
            _adorner = null;
        }
    }

The changes themselves use the concept of MyObject as the payload, instead of string, and the ObservableCollection as the array where you do the changes, instead of the IEnumerable.

Hope this solves your problem.

Lupu Silviu
  • 1,145
  • 11
  • 23