删除ObservableCollection中的一个Item

Jer*_*ian 9 .net c# wpf

我有一些方法,如:

public void RemoveItem(ObservableCollection<SomeClass> collection, SomeClass instance)
{
    if(collection.Contains(instance))
    {
        collection.Remove(instance);
    }
}
Run Code Online (Sandbox Code Playgroud)

首先,即使集合包含实例,if句子仍然返回false.

其次,我删除了if句子,只是让集合可以删除实例.并且在执行之后,集合仍保留其原始项目,其中仍包含实例.

是引用问题,但如何解决?我只是想从的ObservableCollection中删除一个项目,并保持其显着的功能(这困扰了我在这里).

She*_*dan 20

您的问题是您正在尝试从不在该集合中的集合中删除对象.它可能具有相同的属性值,但它不是同一个对象.如果您的对象具有唯一可识别的属性,则有一种简单的方法,例如Id:

public void RemoveItem(ObservableCollection<SomeClass> collection, SomeClass instance)
{
    collection.Remove(collection.Where(i => i.Id == instance.Id).Single());
}
Run Code Online (Sandbox Code Playgroud)

我们的想法是,我们从集合中获取实际项目,然后将其传递给Remove方法.

  • 也许你应该使用`collection.Remove(collection.SingleOrDefault(i => i.Id == instance.Id));`而不是.没有必要在`Where`后面直接跟一个`First`,`Single`等等.在他的原始代码中,似乎`instance`可能不在那里.所以你不应该使用`Single`,如果没有匹配则会爆炸.在任一版本中,隐含地假设`collection`不包含`SomeClass`的`null`值. (3认同)

San*_*tux 6

如果您打算删除的项目具有可以与其他项目进行比较的代码/ID 之类的内容,您可以执行以下操作:

foreach (var item in itemSet)
{
  if (item.ItemID == itemToCompareTo.ItemID)
  {
    itemSet.Remove(item);
    break;
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 我认为您必须在 remove 语句之后立即添加 `break;`。否则枚举将继续,这将导致异常,因为在 `foreach` 期间集合已更改。 (4认同)

Dud*_*lou 4

这似乎确实是一个参考问题。您可能必须重写 Equals(和 GetHashCode)方法,以便 ObservableCollection 能够找到实例,即使它不是同一个引用。

原因是因为 Equals() 方法的默认实现会检查两个对象是否具有相同的引用。

注意:重写 Equals 方法时要小心。您还必须重写 GetHashCode,因为 GetHashCode() 方法的默认实现基于对象的引用返回一个整数,而不是基于对象的实例(和类)变量的值。

无论其实例变量(数据字段)的值更改多少次,默认实现计算的哈希码在对象的生命周期内都不会更改。这就是为什么当您重写 Equals() 方法时我们总是实现 GetHashCode()。

有关此内容的更多信息,请参阅 msdn:Object.Equals 方法(对象)