简体   繁体   English

从wp8中的可观察集合中删除项目

[英]Delete item from observable collection in wp8

I have an observable collection linked to a LongListItemSelector and this parts works fine. 我有一个链接到LongListItemSelector的可观察集合,并且这部分工作正常。

I use the checkbox selection method, which builds a list in the background and this list is passed as a parameter when I click on my Delete button. 我使用复选框选择方法,该方法在后台构建一个列表,当我单击“删除”按钮时,此列表将作为参数传递。 In the Delete button method defined in my ViewModel, I have the following code: 在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);
}

Where selectedFavorites is of type List<Object> and contains the items selected via a checkbox. 其中selectedFavorites的类型为List<Object>并包含通过复选框选择的项目。

Each of the "object" is of type FavoriteItemViewModel . 每个“对象”的类型都是FavoriteItemViewModel As the "object" contained in the list are slightly different from the one contained in my Favorites ObservableCollection, I make sure to first find the item in Favorites based on their Description as this should match. 由于列表中包含的“对象”与我的收藏夹ObservableCollection中包含的对象略有不同,因此我确保首先根据其说明在“收藏夹”中找到该项目,因为这应该匹配。

If found, I delete it but I can this that the item is not actually being removed from Favorites observable collection. 如果找到,我将其删除,但是我可以做到这一点,即实际上并未从“ Favorites可观察集合中删除该项目。

I understand you cannot use a For Each to loop through an observable collection and try to remove an item directly, but I'm not doing that. 我了解您不能使用For Each来遍历可观察的集合并尝试直接删除项目,但是我没有这样做。

I've tried different scenarios but getting nowhere with it. 我尝试了不同的方案,但是毫无用处。

Any ideas what I'm doing wrong? 有什么想法我做错了吗?

Thanks. 谢谢。

解决问题后,唯一可以做的就是使用removeall linq而不是其他列表。

Favorites.RemoveAll(a => selectedFavorites.Exists(w => ((FavoriteItemViewModel)w).Description == a.Description));

I figured out the problem... Couple of mistake on my part! 我发现了问题...我犯了几个错误!

First problem: How my property Favorites was defined: 第一个问题:如何定义我的属性“收藏夹”:

    public ObservableCollection<FavoriteItemViewModel> Favorites
    {
        get
        {
            return _favorites ?? (this.LoadFavorites(App.MainViewModel.Favorites));
        }
        set
        {
            _favorites = value;
        }
    }

The get part never actually set the internal variable, thus reloading the data over and over again from the Favorites collection held in my MainViewModel. get部分从未真正设置内部变量,因此一次又一次地从MainViewModel中保存的收藏夹集合中重新加载数据。

I changed it from: 我将其更改为:

return _favorites ?? (this.LoadFavorites(App.MainViewModel.Favorites));

to

return _favorites ?? (_favorites = this.LoadFavorites(App.MainViewModel.Favorites));

Doooh!! Doooh!

The second problem: 第二个问题:

So while the following is not directly removing the object from my observable collection 因此,尽管以下内容并未直接从我的可观察集合中删除该对象

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);
   }
 }

The parameter actionParameter passed via the CommandParameter ie List, is the List of selected objects from my LongListSelector (Custom one to handle MVVM). 通过CommandParameter即List传递的参数actionParameter是我的LongListSelector(用于处理MVVM的自定义对象)中选定对象的列表。 This List is directly affected whenever an item is selected or unselected. 每当选择或取消选择一个项目时,此列表都会直接受到影响。

I assumed that this parameter would have been passed by value but this doesn't appear to be the case and is in fact passed by reference. 我假设此参数将按值传递,但事实并非如此,实际上是通过引用传递的。

So calling 所以打电话

this.Favorites.Remove(itemToDelete)

does not work either as the second I remove it from the observable collection, it also affect the local variable selectedFavorites list which was assigned the actionParameter variable and I get the typical error: 由于第二次将其从可观察的集合中删除,它也不起作用,它还影响到已分配了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.`

If I use a for loop, while I don't get the error, assuming that I have 2 items selected, the second I remove the first item from the Favorites observable collection, selectedFavorites.count drops from 2 to 1 and causes my for loop to finish too early. 如果我使用for循环,则在没有错误的情况下,假设我选择了2个项目,第二个我从“收藏夹”可观察集合中删除了第一个项目,selectedFavorites.count从2下降到1并导致我的for循环还为时过早

So the only work around was to first build a separate list based on the selectedFavorites list then simply use a for each loop. 因此,唯一的解决方法是首先基于selectedFavorites列表构建一个单独的列表,然后for each循环使用a。

The final code looks like this: 最终代码如下所示:

    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;
    }

And this works as expected! 并且这按预期工作!

You can use prameterized constructor of List<T> to construct new List containing items from existing List without manual foreach loop. 您可以使用List<T>的参数化构造函数构造包含现有List中项目的新List ,而无需手动foreach循环。 Something like this should be enough : 像这样的东西就足够了:

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);
    }
}

Normally We wouldn't need to call Clear() and set selectedFavorites to null because the variable it self declared in local context, so it will be qualified for garbage-collection soon after the method execution finished. 通常,我们不需要调用Clear()并将selectedFavorites设置为null因为它是在本地上下文中自行声明的变量,因此在方法执行完成后不久便可以进行垃圾回收。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM