2011-04-09 75 views
1

注意:我自己可以通过创建一个实现INotifyCollectionChanged的类来暴力破解,但感觉就像已经解决了一些问题,而且我还没有找到正确的位置。如何创建一个'live'集合,它是concat/union/2(或更多)其他集合的集合?

在我的viewmodel的一些地方,我收集了一些有效的特定实体,这些实体从我的域上下文(我们称之为SomeEntitySet)开始,添加了一些少量的“特殊”实例前面,最后,有时两者)。目前我将它作为一个简单的ObservableCollection(我们将其称为SupplementedEntitySet)来实现,每当我更新特定的实体集合时,我都有回调函数来重新填充这个SupplementedEntitySet。引发域上下文的实体是只读的,所以我不能在那里添加'特殊'实例(而且我真的不想再这样做,因为我不希望它们写回数据库)。

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

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

在概念层面上,我通常会看到像Rx这样的东西,但至少在此刻,我不明白我会如何使用它,以便我仍然有一个“拉”集合对于绑定作为ItemsSource的一些ItemsControl(网格,组合框,列表框,不管)

当然,这是一个更通用的问题的具体情况 - 如何有'活'linq查询输出 - 你可能想'活'集合是源的子集,或投影,或某种组合,或其他。就像我们有IEnumerable,IQueryable和IObservable的LINQ提供者,感觉我们可以/应该有IObservableCollection(其中IObservableCollection:ICollection,INotifyCollectionChanged或类似的东西)的提供者

更通用的框架/提供者/无论看起来相当复杂(特别是以高性能的方式实现它),至少在此刻,我只是在寻找源集合的特定场景(在这种情况下是ObservableCollection,即使DomainContext只会将它们公开为IEnumerable)

我在想这个错吗?

+1

有一个项目Continous Linq:http://clinq.codeplex.com/,但它不支持Union,只有Concat和Except。你也可以看看Bindable Linq http://bindablelinq.codeplex.com/。我不知道他们能否在这种特殊情况下提供帮助。 – vorrtex 2011-04-10 11:00:53

回答

1

你在你的问题中提到了Rx,但你不知道如何最终得到绑定的“拉”集合。这很容易。你只需要“推”你的“拉”收藏。

开始像这样的问题:

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

主题是IObservable & 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); 
}); 

这样,你只需要更新一次的主题和所有相关的视图模型得到自动的更新。 :-)