我有一个可观察的集合链接到LongListItemSelector,这部分工作正常。
我使用复选框选择方法,该方法在后台构建列表,当我单击“删除”按钮时,此列表将作为参数传递。在我的ViewModel中定义的Delete按钮方法中,我有以下代码:
foreach (FavoriteItemViewModel item in selectedFavorites)
{
FavoriteItemViewModel itemToDeleted = this.Favorites
.FirstOrDefault<FavoriteItemViewModel>(m =>
m.Description.ToLowerInvariant() == item.Description.ToLowerInvariant());
if (itemToDeleted != null)
this.Favorites.Remove(itemToDeleted);
}
其中selectedFavorites
的类型为List<Object>
,并且包含通过复选框选择的项目。
每个&#34;对象&#34;属于FavoriteItemViewModel
类型。作为&#34;对象&#34;列表中包含的内容与我的收藏夹ObservableCollection中包含的内容略有不同,我确保首先根据描述找到收藏夹中的项目,因为这应该匹配。
如果找到,我会删除它,但我可以这样,该项目实际上并未从Favorites
可观察集合中删除。
我知道你不能使用For Each循环浏览一个可观察的集合并尝试直接删除一个项目,但我没有这样做。
我尝试过不同的场景,但无处可去。
任何想法我做错了什么?
感谢。
答案 0 :(得分:0)
问题解决后,只能使用removeall linq代替其他列表。
Favorites.RemoveAll(a => selectedFavorites.Exists(w => ((FavoriteItemViewModel)w).Description == a.Description));
答案 1 :(得分:0)
我想出了问题......我的一些错误!
第一个问题:我的属性收藏夹是如何定义的:
public ObservableCollection<FavoriteItemViewModel> Favorites
{
get
{
return _favorites ?? (this.LoadFavorites(App.MainViewModel.Favorites));
}
set
{
_favorites = value;
}
}
get
部分从未实际设置内部变量,因此从MainViewModel中保存的Favorites集合中反复重新加载数据。
我改变了:
return _favorites ?? (this.LoadFavorites(App.MainViewModel.Favorites));
到
return _favorites ?? (_favorites = this.LoadFavorites(App.MainViewModel.Favorites));
Doooh !!
第二个问题:
因此,以下内容并非直接从我的可观察集合中删除对象
private void DeleteAction(object actionParameter)
{
List<object> selectedFavorites = actionParameter as List<object>;
foreach (FavoriteItemViewModel item in selectedFavorites)
{
FavoriteItemViewModel itemToDelete =
this.Favorites.FirstOrDefault<FavoriteItemViewModel>
(m => m.Description.ToLowerInvariant() == item.Description.ToLowerInvariant());
if (itemToDelete != null)
this.Favorites.Remove(itemToDelete);
}
}
通过CommandParameter传递的参数actionParameter
,即List,是我的LongListSelector中的所选对象的List(用于处理MVVM的自定义对象)。无论何时选择或取消选择项目,此列表都会受到直接影响。
我认为这个参数是按值传递的,但事实并非如此,实际上是通过引用传递的。
所以打电话
this.Favorites.Remove(itemToDelete)
不能正常工作,因为第二个我将它从可观察集合中删除,它也会影响分配了actionParameter变量的局部变量selectedFavorites
列表,我得到了典型的错误:
An exception of type 'System.InvalidOperationException' occurred in
mscorlib.ni.dll but was not handled in user code
Additional information: Collection was modified; enumeration
operation may not execute.`
如果我使用for
循环,虽然我没有收到错误,假设我选择了2个项目,第二个我从收藏夹可观察集合中删除第一个项目,selectedFavorites.count drop从2到1并导致我的for
循环过早完成。
因此,唯一的解决方法是首先基于selectedFavorites
列表构建单独的列表,然后只使用for each
循环。
最终代码如下:
private void DeleteAction(object actionParameter)
{
List<object> selectedFavorites = actionParameter as List<object>;
List<FavoriteItemViewModel> myList = new List<FavoriteItemViewModel>();
Favorites.RemoveAll(a => selectedFavorites.Exists(w => ((FavoriteItemViewModel)w).Description == a.Description));
myList = null;
}
这可以按预期工作!
答案 2 :(得分:0)
您可以使用List<T>
的参数化构造函数构建包含现有List
的新List
项,而无需手动foreach
循环。这样的事情应该足够了:
private void DeleteAction(object actionParameter)
{
List<object> selectedFavorites =
new List<object>(actionParameter as List<object>);
foreach (var item in selectedFavorites)
{
this.Favorites.Remove((FavoriteItemViewModel)item);
}
}
通常我们不需要调用Clear()
并将selectedFavorites
设置为null
,因为它在本地上下文中自我声明的变量,因此它将被限定为垃圾收集方法执行完成后不久。