使用Move()的ObservableCollection?

时间:2012-05-29 13:03:48

标签: c# wpf

我有一个observablecollection与一个项目列表相关联 UI。 (observablecollection不绑定到UI中的项目。)

现在,用户可以选择多项选择项目并通过拖放重新排序。 所以,如果我有1,2,3,4,5,6,7,8项。例如,用户选择4,6,8并选择在第1项和第2项之间插入,然后新的列表顺序将是,

1,4,6,8,2,3,5,7。

如何使用Move()函数更新AT ONCE列表?

如果我使用移动一次,列表已经处于不同状态......?我应该在单独的数组中跟踪旧索引然后移动它们吗?这是最好的方法吗? 感谢您的任何建议。

2 个答案:

答案 0 :(得分:1)

如果您的目标是仅提升一次CollectionChanged处理程序 - 您可以继承ObservableCollection(它没有密封),并添加一个名为RaiseCollectionChanged的bool属性,在任何静默更新之前将其设置为true。

在此集合中实际执行移动的方法是受保护的和虚拟的 - 因此您可以在调用base.MoveItem(它引发事件)之前覆盖并检查RaiseCollectionChanged。

维护在静默模式下修改集合时标记的标志也是一个好主意。这样,当RaiseCollectionChanged再次设置为true时,您可以立即为所有修改的项目引发事件。

答案 1 :(得分:0)

评论中的帖子太长,所以它在这里作为答案 当发布 ananthonline 时,您可以继承ObservableCollection。

但不幸的是,这只是工作的一半。原因是集合隐式使用集合视图作为项控件的源项绑定。

CollectionView用作WPF中所有默认集合视图的基本类型,并不支持批量收集更新:

private void ValidateCollectionChangedEventArgs(NotifyCollectionChangedEventArgs e)
{
    switch (e.Action)
    {
        case NotifyCollectionChangedAction.Add:
        {
            if (e.NewItems.Count != 1)
            {
                throw new NotSupportedException(SR.Get("RangeActionsNotSupported"));
            }
            break;
        }
        case NotifyCollectionChangedAction.Remove:
        {
            if (e.OldItems.Count != 1)
            {
                throw new NotSupportedException(SR.Get("RangeActionsNotSupported"));
            }
            if (e.OldStartingIndex < 0)
            {
                throw new InvalidOperationException(SR.Get("RemovedItemNotFound"));
            }
            break;
        }
        case NotifyCollectionChangedAction.Replace:
        {
            if (e.NewItems.Count != 1 || e.OldItems.Count != 1)
            {
                throw new NotSupportedException(SR.Get("RangeActionsNotSupported"));
            }
            break;
        }
        case NotifyCollectionChangedAction.Move:
        {
            if (e.NewItems.Count != 1)
            {
                throw new NotSupportedException(SR.Get("RangeActionsNotSupported"));
            }
            if (e.NewStartingIndex < 0)
            {
                throw new InvalidOperationException(SR.Get("CannotMoveToUnknownPosition"));
            }
            break;
        }
        case NotifyCollectionChangedAction.Reset:
        {
            break;
        }
        default:
        {
            throw new NotSupportedException(SR.Get("UnexpectedCollectionChangeAction", new object[]
            {
                e.Action
            }));
        }
    }
}

...你必须实现ICollectionView。我不确定,这是正确的方式。