注意:我当然可以通过创建一个实现INotifyCollectionChanged的类来强行解决这个问题,但感觉好像已经解决了,我只是还没有找到正确的地方。
在我的视图模型的几个地方,我有集合,有效地一些特定的实体设置我的域上下文(我们称之为SomeEntitySet)与一些小的"特殊"实例添加到它(在前面,在最后,有时两者)。目前,我将其实现为一个简单的ObservableCollection(我们将其称为supplements entityset),每当我更新特定的实体集时,我让回调也重新填充这个supplements entityset。域上下文的实体设置是只读的,所以我不能在那里添加"特殊"实例(而且我真的不想这样做,因为我不希望它们被写回数据库)。
对于这个场景,让我们假设1)我不想修改RIA查询来包含这些"特殊"实体2)我不想在使用站点包含绑定转换器来添加它们,等等
虽然你可能不会使用这种特殊的机制这样做,作为一个示例场景,让我们假设你有一个类别列表从RIA调用返回,但是你希望你绑定组合框的集合也有一个特殊的"所有项目"类别(再次,不想通过转换器或类似的方式添加它)。
在概念层面上,我通常会看到像Rx这样的东西,但至少在目前,我不知道我会如何使用,这样我仍然有一个"拉"集合,用于将ItemsSource绑定到一些ItemsControl (grid, combobox, listbox, whatever)
当然,这是一个更普遍的问题的具体情况-如何拥有"实时"linq查询输出-你可能希望"实时"集合是源的子集,或投影,或某些组合,或其他什么。就像我们为IEnumerable, IQueryable和IObservable提供了LINQ提供商一样,感觉我们可以/应该为IObservableCollection(其中IObservableCollection: ICollection, INotifyCollectionChanged或类似的东西)提供提供商
更通用的框架/提供程序/任何看起来相当复杂(特别是以一种高性能的方式实现它),所以至少在目前,我只是寻找源集合的特定场景(在这种情况下,一个ObservableCollection,即使DomainContext只将它们暴露为IEnumerable)
我想错了吗?
您在问题中提到了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);
});
这样,你只需要更新主题一次,所有相关的视图模型都会自动更新。: -)