注意:我当然可以通过创建一个实现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)
我在考虑这个错误吗?
答案 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);
});
这样,您只需更新主题一次,所有关联的视图模型都会自动更新。 : - )