2009-02-09 27 views
14

Derzeit verwende ich eine ObservableCollection in einer WPF-Anwendung, die Anwendung ist eine Implementierung von Conways Spiel des Lebens und funktioniert gut für etwa 500 Zellen, aber danach beginnt es deutlich zu verlangsamen. Ich habe die Anwendung ursprünglich mit einem HashSet geschrieben, konnte aber keine Möglichkeit finden, die Zellen an eine Arbeitsfläche zu binden.Wie kann ich einen Observable Hashset in C# erstellen?

Gibt es eine Möglichkeit, mein HashSet zu veranlassen, sein bindendes Objekt von Änderungen zu benachrichtigen? Meine Cell-Klasse ist ein einfaches Integer-X-, Y-Paar, wenn das Paar existiert, ist die Zelle am Leben, ansonsten tot. Die Zelle implementiert INotifyPropertyChanged und überschreibt GetHashCode und Equals. Ich konnte die Zelle nicht dazu bringen, irgendwelche Änderungen anzuzeigen, nur die Zellen, die unmittelbar nach dem Laden vorhanden waren. Gibt es eine Möglichkeit, einen Hash-Satz an Elemente in einem Canvas zu binden?

Antwort

10

Sie müssen auch INotifyCollectionChanged implementieren, und dann sollte alles OK funktionieren. Es gibt eine andere relevante SO-Antwort, die uses freezables, um sicherzustellen, dass Änderungen in zugrunde liegenden Entitäten auch behandelt werden.

+0

Hmm, ich schaue mir das an, INotifyCollectionChanged könnte nur mein fehlender Link sein, danke! – Michael

12

Ich weiß nicht, ob dies helfen wird, aber hier ist eine wirklich einfache Implementierung eines "beobachtbaren Set", das ich für ein persönliches Projekt gemacht habe. Es schützt im Wesentlichen davor, ein Objekt, das bereits in der Sammlung ist, einzufügen (oder zu überschreiben).

Wenn Sie wollten, könnten Sie einfach aus den Methoden zurückkehren, anstatt eine Ausnahme zu werfen.

public class SetCollection<T> : ObservableCollection<T> 
{ 
    protected override void InsertItem(int index, T item) 
    { 
     if (Contains(item)) throw new ItemExistsException(item); 

     base.InsertItem(index, item); 
    } 

    protected override void SetItem(int index, T item) 
    { 
     int i = IndexOf(item); 
     if (i >= 0 && i != index) throw new ItemExistsException(item); 

     base.SetItem(index, item); 
    } 
} 
+0

Dies ist sehr nah an dem, was ich bereits habe, ich benutze eine observablecollection und garantiere einfach, dass alle Artikel einzigartig sind. In meinem Code anstatt durch Vererbung, aber hey, ich bin ein Weichei;) – Michael

+0

Ja, ich würde sagen, dass dies einfacher ist als HashSet neu zu implementieren, so dass es INotifyCollectionChanged implementiert. All die harte Arbeit wird bereits von ObservableCollection für Sie erledigt. –

+0

von Reflektor gehen scheint, dass Sie nur den Standardkonstruktor verfügbar machen oder die anderen selbst implementieren möchten, da die Basis eine private 'CopyFrom'-Methode anstelle von' InsertItem' – Maslow

11

Ich habe hier eine vollständige ObservableHashSet veröffentlicht, die Sie verwenden können.

https://github.com/BellaCode/Public/tree/master/ObservableHashSet

Es basiert zu reflektieren, wie ObservableCollection implementiert und bietet die gleichen Neueintritt Kontrollen Thread-Sicherheit.

+0

Super, vielen Dank für das Teilen! – Dav

+0

Es ist nett, aber um die Sammlungen 'newItems',' oldItems' zu füllen, müssen Sie einige wirklich langsame Operationen durchführen. Ich würde wahrscheinlich eine Option hinzufügen, um diese überhaupt nicht zu füllen, und nur berichten, dass sich etwas geändert hat, indem ich das Ereignis ausgelöst habe. – Magnus

+8

'int index = this.hashSet.IndexOf (Element);' error 'Fehler 'System.Collections.Generic.HashSet ' enthält keine Definition für 'IndexOf' und keine Erweiterungsmethode 'IndexOf', die eine erste akzeptiert Argument des Typs 'System.Collections.Generic.HashSet ' könnte gefunden werden (fehlt eine using-Direktive oder eine Assembly-Referenz?) ' – AgentFire

Verwandte Themen