2010-11-29 19 views
6

Ist es möglich, die Größe einer Observable Collection zu ändern oder die maximale Anzahl von Sammelobjekten einzuschränken? Ich habe eine ObservableCollection als Eigenschaft in einem View-Modell (mit dem MVVM-Muster).Wie ändere ich die Größe von ObservableCollection?

Die Ansicht bindet an die Auflistung und ich habe versucht, eine Lösung zu hacken, indem Sie einen Ereignishandler bereitstellen, der ausgeführt wird, wenn ein CollectionChanged-Ereignis auftritt. Im Ereignishandler habe ich die Sammlung gekürzt, indem ich so viele Objekte wie nötig aus dem oberen Bereich der Sammlung entfernt habe.

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

Dieser Event-Handler liefert ein InvalidOperationException, weil es nicht die Tatsache, dass ich die Sammlung während eines CollectionChanged Ereignis ändern. Was soll ich tun, um meine Sammlung angemessen zu halten?

Lösung: Simon Mourier gefragt, ob ich eine neue Kollektion von ObservableCollection<T> abgeleitet schaffen könnte, und überschreiben InsertItem() und das ist genau das, was ich ein Auto-Größenänderung ObservableCollection Typ hatte.

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

Antwort

8

Können Sie die ObservableCollection-Klasse ableiten und die InsertItem-Methode überschreiben?

+0

Ist es trivial, dies zu tun? Ich habe auf eine Antwort gehofft und nicht auf eine andere Frage :) – jlafay

+0

Ihre Idee hat funktioniert, ich wünschte nur, Sie hätten mehr ausgearbeitet. Wie auch immer, ich füge meine Lösung zu meiner Frage hinzu. Danke für die Hilfe. – jlafay

+0

Froh, es hat funktioniert. Gute Arbeit jedenfalls :) –

3

Sie können eine eigene Sammlungsklasse erstellen, die INotifyCollectionChanged und INotifyPropertyChanged implementiert. Sie können es relativ einfach tun, indem Sie ObservableCollection intern in Ihrer eigenen Sammlungsklasse verwenden.

6

versuchen Sie stattdessen:

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

Das ist ziemlich viel, was ich mit mir selbst ging, wie von Simon vorgeschlagen. – jlafay

Verwandte Themen