Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to resize ObservableCollection?

Is it possible to resize an Observable Collection or perhaps restrict the max amount of collection items? I have an ObservableCollection as a property in a View Model (using the MVVM pattern).

The view binds to the collection and I've attempted to hack a solution by providing an event handler that executes when a CollectionChanged event occurs. In the event handler, I trimmed the collection by removing as many items off the top of the collection as necessary.

ObservableCollection<string> items = new ObservableCollection<string>();
items.CollectionChanged += new NotifyCollectionChangedEventHandler(Items_Changed);

void Items_Changed(object sender, NotifyCollectionChangedEventArgs e)
{
    if(items.Count > 10)
    {
        int trimCount = items.Count - 10;
        for(int i = 0; i < trimCount; i++)
        {
            items.Remove(items[0]);
        }
    }
}

This event handler yields an InvalidOperationException because it doesn't like the fact that I alter the collection during a CollectionChanged event. What should I do to keep my collection sized appropriately?

Solution: Simon Mourier asked if I could create a new collection derived from ObservableCollection<T> and override InsertItem() and thats just what I did to have an auto-resizing ObservableCollection type.

public class MyCollection<T> : ObservableCollection<T>
{
    public int MaxCollectionSize { get; set; }

    public MyCollection(int maxCollectionSize = 0) : base()
    {
        MaxCollectionSize = maxCollectionsize;
    }

    protected override void InsertItem(int index, T item)
    {
        base.InsertItem(index, item);

        if(MaxCollectionSize > 0 && MaxCollectionSize < Count)
        {
            int trimCount = Count - MaxCollectionSize;
            for(int i=0; i<trimCount; i++)
            {
                RemoveAt(0);
            }
        }
    }
}
like image 830
Jeff LaFay Avatar asked Nov 29 '10 16:11

Jeff LaFay


3 Answers

Can you derive the ObservableCollection class and override the InsertItem method?

like image 122
Simon Mourier Avatar answered Sep 18 '22 14:09

Simon Mourier


try this instead:

public class FixedSizeObservableCollection<T> : ObservableCollection<T>
{
    private readonly int maxSize;
    public FixedSizeObservableCollection(int maxSize)
    {
        this.maxSize = maxSize;
    }

    protected override void InsertItem(int index, T item)
    {
        if (Count == maxSize)
            return; // or throw exception
        base.InsertItem(index, item);
    }
}
like image 43
Dean Chalk Avatar answered Sep 21 '22 14:09

Dean Chalk


You can roll your own collection class that implements INotifyCollectionChanged and INotifyPropertyChanged. You can do it fairly easily by using ObservableCollection internally in your own collection class.

like image 29
Jakob Christensen Avatar answered Sep 22 '22 14:09

Jakob Christensen