Stacey
Stacey

Reputation: 141

Duplicate an ObservableCollection Item

I want to duplicate a list item in an observablecollection. When I do:

            TreasureCards[TreasureCards.Count - 1] = TreasureCards[CardPosition];

It creates a copy of the specific list item but then they are linked in my UI. So if I change the new duplicated item's name, it changes the originals name. I know I could do each of the properties one by one (see below) but is there a way to just copy the entire item?

    TreasureCards[TreasureCards.Count - 1].Name = TreasurecCards[CardPosition].Name;
    TreasureCards[TreasureCards.Count - 1].Type= TreasurecCards[CardPosition].Type;

// etc

Upvotes: 1

Views: 8457

Answers (2)

Robert Rossney
Robert Rossney

Reputation: 96730

You aren't duplicating the object. You're creating a new reference to the object. There's still only one object; now there are two references to it in your collection, and any change to the object is reflected by both references.

To create a new object, you can call MemberwiseClone() on anything that derives from Object. This method returns a new instance, copying the values from all fields in the original object. So you'd do:

TreasureCards[TreasureCards.Count - 1] = TreasureCards[CardPosition].MemberwiseClone();

There are two limitations with this method. First, it's a shallow copy, i.e. any reference fields in the original object have their values copied. So if a.Foo is a reference to a Bar object, a.MemberwiseClone().Foo will refer to the same Bar object. Second, the method just copies the fields; it doesn't call the new object's constructor. Depending on the design of the class, this is either unimportant or a Really Big Deal.

Usually, it's safer to make the class implement ICloneable and explicitly implement a Clone() method, e.g.:

public TreasureCard Clone()
{
   return new TreasureCard
   {
      Name = this.Name,
      Type = this.Type,
      ...
   };
}

Upvotes: 5

CodingGorilla
CodingGorilla

Reputation: 19842

They aren't linked, they are the same instance. All you're doing is copying a reference to the same data to another position in the array.

What you need to do is implement some Clone method that makes a copy of the original instance but as another instance. This SO post might help.

Then you would do something like this:

 TreasureCards[TreasureCards.Count - 1] = TreasureCards[CardPosition].Clone();

Upvotes: 1

Related Questions