我有一个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
范例一起使用的设计意图吗?
使用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多次重复同一集合并创建其他集合相比,这不是“笨拙”。