如何克隆ObservableCollection <t> .CollectionChanged事件?</t>

时间:2012-08-10 15:52:16

标签: c# silverlight

我正在尝试将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事件。

任何方式这样做? 感谢

编辑:

之前: Before the constructor call 后: After the constructor call

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

    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);
    ...
    }

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

2 个答案:

答案 0 :(得分:3)

如果我正确理解您的问题,您希望将observable集合替换为另一个,但您仍然希望在新集合发生更改时通知旧集合上的事件订阅者。

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

PartitionCollection中,您可以覆盖ClearItemsInsertItemRemoveItemSetItem,并在调用基类实现后将更改转发给旧集合新集合中的方法。这应保持同步。

如果您只想要集合的sinlge副本,则可以从PartitionCollection派生IObservableCollection<AislePartition>并为您提供自己的接口实现。然后,此集合的后备存储应为旧集合。这个解决方案非常繁琐,因为你必须实现许多方法,这些方法只是转发器包含在包装集合上的相同方法,但是你可以确保不复制集合。

如果可以通过其他方式修改旧集合而不是通过包装器修改旧集合,则必须订阅旧集合上的更改并从包装器中触发类似事件。

如果您真的想要,可以使用一些"evil" tricks来访问旧集合的调用列表。但是,在这之前我会三思而行。

答案 1 :(得分:1)

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

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

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