如何创建一个'live'集合,它是concat / union / 2个(或更多)其他集合的集合?

时间:2011-04-09 19:20:20

标签: silverlight linq silverlight-4.0 wcf-ria-services

注意:我当然可以通过创建一个实现INotifyCollectionChanged的类来强制执行此操作,但感觉就像已经解决的东西,我还没有找到正确的位置。

在我的viewmodel中的一些地方,我的集合实际上是我的域上下文中的一些特定实体(我们称之为SomeEntitySet),并添加了一些小的“特殊”实例(在前面) ,最后,有时两者都是)。目前我将它实现为一个简单的ObservableCollection(我们称之为SupplementedEntitySet),每当我更新特定的实体集时,我都有回调也重新填充这个SupplementedEntitySet。域上下文的实体是readonly,所以我不能在那里添加'特殊'实例(我真的不想要,因为我不希望它们写回数据库)。

对于这种情况,我们假设1)我不想修改RIA查询以包含这些“特殊”实体2)我不想在使用站点包含绑定转换器来添加它们等等。

虽然您可能不会使用此特定机制这样做,但作为一个示例场景,假设您有一个从RIA调用返回的类别列表,但您希望绑定组合框的集合具有一个特殊的“所有项目”类别(同样,不想通过转换器等添加它)。

在概念层面上,我通常会看到像Rx这样的东西,但至少在目前,我看不出我会如何使用它,以至于我仍然有一个'pull'集合对于绑定很有用作为ItemsSource的ItemsSource(网格,组合框,列表框,等等)

当然,这是一个更通用问题的特定情况 - 如何使用'实时'linq查询输出 - 您可能需要'实时'集合作为源的子集,或投影,或某种组合,或其他什么。就像我们为IEnumerable,IQueryable和IObservable提供LINQ提供程序一样,感觉我们可以/应该有像IObservableCollection这样的提供程序(其中IObservableCollection:ICollection,INotifyCollectionChanged或类似的东西)

那个更通用的框架/提供者/看起来很复杂(特别是以高效的方式实现它),所以至少在目前,我只是在寻找源集合的特定场景(在这种情况下, ObservableCollection,即使DomainContext只将它们公开为IEnumerable)

我在考虑这个错误吗?

1 个答案:

答案 0 :(得分:1)

你在问题​​中提到了Rx,但是你不确定如何以绑定的“拉”集合结束。这很简单。你只需要“推”你的“拉”系列。

从这样的主题开始:

var updatedItems = new Subject<IEnumerable<string>>();

主题为IObservable&amp;同时IObserver。因此,每次从RIA服务中获取项目时,只需在主题上调用OnNext即可。

// first result from RIA service call
updatedItems.OnNext(new [] { "A", "B", });

// sometime later another result
updatedItems.OnNext(new [] { "X", "Y", });

现在您可以像这样更新ObservableCollection

var itemsObservableList = new ObservableCollection<string>();

var extras = new [] { "<all items>" };

var supplementedItems = 
    from items in updatedItems
    select extras.Concat(items);

supplementedItems.Subscribe(items =>
{
    itemsObservableList.Clear();
    items.Run(itemsObservableList.Add);
});

这样,您只需更新主题一次,所有关联的视图模型都会自动更新。 : - )