Click here to Skip to main content
15,879,474 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hi all,
I am just playing around with some ideas and was wondering if the following would be possible without too much hassle...

Imagine a class like this:
C#
public class Animals : ObservableCollection<Animal>
{
}

And of course this radically rare class
C#
public class Animal
{
     public string Name{ get; set; }
     public bool IsAlive{ get; set; }
     public bool Buried{ get; set; }
}


Now if someone uses the Animals class he/she would propably not be interested in retrieving animals that are not alive and buried (if so I could provide a function to get these if neccessary).

So would it somehow be possible to modify the Animals class so that it only respects instances of Animal that are actually alive and not buried?
So after an instance of Animal is actually buried (and of course no longer alive - which might automatically change if buried alive) it should not be available anymore by using the standard retrieval methods of the Animals class (also Count and Linq related stuff like First, Where, etc. - you get the picture).

So far I implemented the INotifyPropertyChanged interface in the Animal class to allow Animals to remove those instances (dead and buried) and store them internally, which works fine. But would there be a more elegant solution to the problem?


UPDATE:
Maybe I can simplify it a little bit more.
Would it be possible to modify the Animals class somehow to only return instances of Animal where not (Alive = false AND Buried = true) so that they can no longer be seen by the outside world but to keep it in the list?
Mabe by overriding/overwriting the enumerator like this:
C#
new public IEnumerator GetEnumerator()
{
    IEnumerator ie = base.GetEnumerator();
    while (ie.MoveNext())
    {
        Animal animal = (Animal)ie.Current;
        if(animal.Alive && !animal.Buried)
        yield return ie.Current;
    }
}

..but would that also affect Count, First, etc of the List?

UPDATE:
I figured out that the above will affect foreach (which was ecpectable) but not Count or Linq methods...



I have hard time expressing myself in english here, please be mercyfull :)



Any thoughts are kindly appreciated,
have a great day
Andy
Posted
Updated 12-Sep-12 3:28am
v8
Comments
Kenneth Haugland 12-Sep-12 8:38am    
Do you wan tsomething that say MyAnimal.Buiried = True then delete this instance of the class?
hoernchenmeister 12-Sep-12 8:54am    
Yes thats somehow right. If an animal dies it gets buried and after that it should no longer be accessible via standard retrieval methods. If anybody would be interested in retrieving a List of dead and buried animals he/she could call a "List<animal> GetDeadAndBuried()" function to retrieve (and maybe unbury and reanimate them) them
Malli_S 12-Sep-12 8:40am    
If you don't wanna to preserve the dead Animals, you should check them while inserting also. Don't insert the dead Animals in the list. Bcz, there's less chance of changing the property from 'Dead' to 'Alive'.
hoernchenmeister 12-Sep-12 8:59am    
Dead animals are not inserted in the list. First they are alive, if they die (become deleted) they become buried at a certain point (committed), thats where they sould no longer be visible by the default retrieval methods (like beeing bound to a grid or something alike).
Malli_S 12-Sep-12 8:43am    
Did you mean have another list of dead animals by saying 'store them internally' ?

1 solution

First of all thanks to Malli_S, Kenneth Haugland and Ashraff Ali Wahab for their contribution. It is very much appreciated!!!

In the end I came up with the following, which solves my problem.

If anybody has a comment on this I would be interested very much in hearing about it.

I only posted the replacement for the ObservableCollection because there is quite a bunch of stuff involved that would be out of the scope of the question.


C#
public abstract class BuryableBaseClassObservableCollection<T> : ObservableCollection<T>, ITransactionEnabled where T : BuryableBaseClass
{
    protected BuryableBaseClassObservableCollection()
    {
        InitializeInternalEvents();
    }

    protected void InitializeInternalEvents()
    {
        this.CollectionChanged += ItemsBaseCollectionChanged;
    }

    void ItemsBaseCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        switch (e.Action)
        {
            case NotifyCollectionChangedAction.Remove:
                Unregister(e.OldItems);
                return;

            case NotifyCollectionChangedAction.Add:
                Register(e.NewItems);
                return;
        }
    }

    protected void Unregister(IList oldItems)
    {
        foreach (T item in oldItems)
        {
            item.PropertyChanged -= ItemPropertyChanged;
            item.ElementCommitted -= ItemElementCommitted;
        }
    }

    protected void Register(IList oldItems)
    {
        foreach (T item in oldItems)
        {
            item.PropertyChanged += ItemPropertyChanged;
            item.ElementCommitted += ItemElementCommitted;
        }
    }

    void ItemElementCommitted(object sender, BuryableBaseClass committedElement)
    {
        T element = committedElement as T;
        if (committedElement.Deleted)
        {
            Console.WriteLine(String.Format("removing element of type: {0}", typeof(T)));
            this.Remove(element);
        }
    }

    void ItemPropertyChanged(object sender, PropertyChangedEventArgs args)
    {
        Console.WriteLine(String.Format("NotifyPropertyChangedPropertyChanged: {0}", args.PropertyName));
    }

    #region Implementation of ITransactionEnabled

    public virtual List<Exception> TransactionExceptions
    {
        get
        {
            List<Exception> retVal = new List<Exception>();
            foreach (ITransactionEnabled itm in this)
            {
                retVal.AddRange(itm.TransactionExceptions);
            }
            return retVal;
        }
    }

    public virtual bool Save()
    {
        return !this.Any(a => !a.Save());
    }

    public virtual void Commit()
    {
        for (int i = this.Count - 1; i >= 0; i--)
        {
            this[i].Commit();
        }
    }

    public virtual void Rollback()
    {
        for (int i = this.Count - 1; i >= 0; i--)
        {
            this[i].Rollback();
        }
    }

    #endregion
}
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900