我有ObservableCollection
个食谱,每个食谱都有ObservableCollection
个配料。假设我要使用Linq修改或从所有食谱中删除某些成分(例如,从所有食谱中删除花生)。我已经尝试做过这样的事情:
foreach(Recipe r in myObservableRecipes)
{
r.ObservableIngredients.RemoveAll(i => i.Type == PEANUTS);
}
但这不起作用,因为成分列表是ObservableCollection,而RemoveAll
是List<T>
方法。如果我添加ToList().RemoveAll()
,实际上并不会从集合中删除它们,而是从集合的副本中删除它们。我找不到一个似乎有效的Remove Where组合,因为Where返回一个没有IEnumerable
调用的Remove
。
我正在做的是:
foreach(Recipe r in myObservableRecipes)
{
var ingToRemove = new HashSet<Ingredient>(r.myObservableIngredients.Where(i => i.Type == PEANUTS));
foreach (Ingredient i in r.myObservableIngredients.ToList())
{
if(ingToRemove.Contains(i)) r.myObservableIngredients.Remove(i);
}
RaisePropertyChangedEvent("myObservableIngredients");
}
这可行,但是在实体集和可观察集合的交集处显得笨拙。实际上,我还从同一循环内的实体集(DeleteOnSubmit
)中删除了相同的实体,然后调用了提交更改。这是将LinqToSQL
实体与WPF和ObservableCollections/CollectionViewSource
范式一起使用的设计意图吗?
答案 0 :(得分:0)
使用ObservableCollection<T>
的全部目的是,您可以在其中添加或删除项,并且可以在不创建任何其他集合的情况下更新UI。
只需使用嵌套的旧式for
循环:
for (int i = myObservableRecipes.Count - 1; i >= 0; --i)
{
Recipe r = myObservableRecipes[i];
for (int j = r.myObservableIngredients.Count - 1; j >= 0; j--)
{
Ingredient ing = r.myObservableIngredients[j];
if (ing.Type == PEANUTS)
r.myObservableIngredients.RemoveAt(j);
}
//remove recipes without any remaining ingredients
if (r.myObservableIngredients.Count == 0)
myObservableRecipes.RemoveAt(i);
}
与使用LINQ多次重复同一集合并创建其他集合相比,这并不“笨拙”。