简体   繁体   中英

How to update ObservableCollection in codeBehind after drag and drop on listview - WPF MVVM

I am having some difficulty when I use the Josh Smith's issue for DnD on listView.

I have an ObservableCollection of "DetailTable" that I initialize in the ViewModel when I create the view :

(ListeTables is CollectionViewSource where I initialize and use my data)

public ObservableCollection<DetailTable> ListeTablesDisplay
{
    get
    {
        var l = ListeTables.View.Cast<DetailTable>().ToList();
        return new ObservableCollection<DetailTable>(l);
    }
}

The listView in the Xaml file :

    <ListView Name="ListeViewTables" SelectionMode="Single" 
              AllowDrop="true"
              ScrollViewer.HorizontalScrollBarVisibility="Disabled" 
              ItemsSource="{Binding ListeTablesDisplay, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" 
              SelectedItem="{Binding SelectedTable, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
              Margin="10,83,831,61">

And then I call the Class of Josh Smith for the DnD in the View CodeBehind :

public DataView()
{
    InitializeComponent();

    new ListViewDragDropManager<DetailTable>(this.ListeViewTables);
}

Until now, the drag and drop work correctly, but in the ViewModel the order of items of the ObservableCollection is not coherent with what I do in the View.

Example : if I move the item-3 to the 5th position, it's ok with the View but when I debug I see the item-3 always to the 3rd position in my ObservableCollection.

It's very problematic for what I want to do, I hope someone can help me !

Thanks

If a person has the same problem, just add the event ProcessDrop on ListViewDragDropManager

Then in the viewModel the event need to move manually the item index in the ObservableCollection

    public static void OnProcessDrop(object sender, ProcessDropEventArgs<T> e)
    {
        e.ItemsSource.Move(e.OldIndex, e.NewIndex);

        e.Effects = DragDropEffects.Move;
    }

Here an example by the autor of ListViewDragDropManager - "Custom drop logic" for help

Here's how to handle this in the general case. OP was able to get it to work as desired with Smith's code by handling Smith's ProcessDrop event.

In the drop handler, determine whether the target ListView's ItemsSource is null.

If you have an ItemsSource , cast it to System.Collections.IList and do the reordering operation on the list , not on Items . Forget Items in this branch. If the items source is an ObservableCollection<T> , the ordering in the ListView will update. If it isn't, that's not your problem. The consumer of your code who provided the wrong list type needs to post a question asking why WPF doesn't get change notifications from List<T> or int[] or String or whatever.

If you don't have an ItemsSource , you just have ListViewItems. Reorder Items . Easy.

I've never before seen Josh Smith's code , and he'd be the guy to talk to if you need updates. Personally, I use an Adorner rather than restyling the list control items, but you can make a case for either approach.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM