2

我正在尝试将 ObservableCollection 复制到 ObservableCollection 派生类型中,并且我想保留 CollectionChanged 事件。

到目前为止,我有:

public class PartitionCollection : ObservableCollection<AislePartition>
{
    public PartitionCollection(ObservableCollection<AislePartition> other)
    : base(other)
    {

    }

    // ...

    protected override void InsertItem(int index, AislePartition item)
    {
         // Important custom logic runs here
         if (/* */)
             base.InsertItem(index, item);
         else
             Merge(item);
    }

    protected void Merge(AislePartition item)
    {
         // ...
    }
}

它可以很好地复制集合,但我也需要获取 CollectionChanged 事件。

有什么办法吗?谢谢

编辑:

之前: 在构造函数调用之前 之后: 在构造函数调用之后

使用此特定构造函数的代码:

    private static void OnSourceChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
    {
        AisleSelection aisleSelect = args.NewValue as AisleSelection;
        if (aisleSelect.Partitions == null)
            aisleSelect.Partitions = new PartitionCollection();
        else
            aisleSelect.Partitions = new PartitionCollection(aisleSelect.Partitions);
    ...
    }

基本上我想要做的是用我的 PartitionCollection 替换 ObservableCollection ,它覆盖了一些关键成员。ObservableCollection 是从服务器以序列化形式传递给我的,所以我无法直接使用它。

4

2 回答 2

3

如果我正确理解您的问题,您想用另一个替换可观察集合,但您仍然希望在新集合更改时通知旧集合上的事件的订阅者。

如果这是正确的,那么您想要的是将旧集合与新集合保持同步。新集合应保留对旧(源)集合的引用,并且每当修改新集合时,您对旧集合执行相同的修改。

在调用新集合中方法的基类实现后,PartitionCollection您可以覆盖ClearItems、和转发对旧集合的更改。这应该保持同步。InsertItemRemoveItemSetItem

如果您绝对只想要一个集合的单一副本,您可以从中派生PartitionCollectionIObservableCollection<AislePartition>为您提供自己的接口实现。这个集合的后备存储应该是旧集合。这个解决方案非常乏味,因为您必须实现许多方法,这些方法只是转发到包装集合上的相同方法,但您要确保不复制集合。

如果可以通过包装器以外的其他方式修改旧集合,您将必须订阅旧集合的更改并从包装器触发类似事件。

如果你真的想的话,有一些“邪恶”的技巧可以让你访问旧集合的调用列表。但是,在这样做之前我会三思而后行。

于 2012-08-10T16:03:19.087 回答
1

您不能只将事件处理程序从一个对象复制到另一个对象,因为事件仅提供两种方法来添加处理程序和删除处理程序......换句话说,您不能枚举处理程序并将它们添加到新对象事件.

我的建议是对旧对象进行弱(或强)处理,并提供一个内部事件处理程序,该处理程序首先调用事件的所有订阅者,然后在提供的对象上调用事件。

请记住,如果您使用强引用,只要当前对象处于活动状态,旧对象就会保持活动状态,因此可能会导致内存泄漏或内存使用过多。

于 2012-08-10T16:09:49.237 回答