如何在listview - WPF MVVM上拖放后更新codeBehind中的ObservableCollection

时间:2022-09-17 14:26:57

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

当我在listView上使用Josh Smith的DnD问题时,我遇到了一些困难。

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

我有一个ObservableCollection“DetailTable”,我在创建视图时在ViewModel中初始化:

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

(ListeTables是CollectionViewSource,我初始化并使用我的数据)

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

The listView in the Xaml file :

Xaml文件中的listView:

    <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 :

然后我在View CodeBehind中为DnD调用Josh Smith的类:

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.

到目前为止,拖放工作正常,但在ViewModel中,ObservableCollection的项目顺序与我在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.

示例:如果我将item-3移动到第5个位置,则可以使用View,但是当我调试时,我看到item-3总是在我的ObservableCollection中的第3个位置。

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

对于我想做的事情来说,这是非常有问题的,我希望有人可以帮助我!

Thanks

2 个解决方案

#1


1  

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

如果一个人有同样的问题,只需在ListViewDragDropManager上添加事件ProcessDrop即可

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

然后在viewModel中,事件需要在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

这里是ListViewDragDropManager的autor示例 - “自定义删除逻辑”的帮助

#2


-1  

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.

以下是在一般情况下如何处理这个问题。通过处理Smith的ProcessDrop事件,OP能够根据需要使用Smith的代码。

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

在drop handler中,确定目标ListView的ItemsSource是否为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.

如果您有ItemsSource,则将其强制转换为System.Collections.IList并对列表执行重新排序操作,而不是对项目执行重新排序操作。忘记此分支中的项目。如果items source是ObservableCollection ,则ListView中的排序将更新。如果不是,那不是你的问题。提供错误列表类型的代码的使用者需要发布一个问题,询问为什么WPF不会从List 或int []或String或其他任何内容获取更改通知。

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

如果您没有ItemsSource,则只需要ListViewItems。重新排序项目。简单。

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.

我以前从未见过Josh Smith的代码,如果你需要更新,他就是那个可以交谈的人。就个人而言,我使用Adorner而不是重新列出列表控件项,但您可以为这两种方法提供案例。

#1


1  

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

如果一个人有同样的问题,只需在ListViewDragDropManager上添加事件ProcessDrop即可

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

然后在viewModel中,事件需要在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

这里是ListViewDragDropManager的autor示例 - “自定义删除逻辑”的帮助

#2


-1  

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.

以下是在一般情况下如何处理这个问题。通过处理Smith的ProcessDrop事件,OP能够根据需要使用Smith的代码。

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

在drop handler中,确定目标ListView的ItemsSource是否为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.

如果您有ItemsSource,则将其强制转换为System.Collections.IList并对列表执行重新排序操作,而不是对项目执行重新排序操作。忘记此分支中的项目。如果items source是ObservableCollection ,则ListView中的排序将更新。如果不是,那不是你的问题。提供错误列表类型的代码的使用者需要发布一个问题,询问为什么WPF不会从List 或int []或String或其他任何内容获取更改通知。

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

如果您没有ItemsSource,则只需要ListViewItems。重新排序项目。简单。

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.

我以前从未见过Josh Smith的代码,如果你需要更新,他就是那个可以交谈的人。就个人而言,我使用Adorner而不是重新列出列表控件项,但您可以为这两种方法提供案例。