Ich suche nach einer Möglichkeit, Daten in einem DataGrid
von Typen anzuzeigen, die zur Kompilierzeit unbekannt sind.
Ich habe die folgende Basisklasse
%Vor% Zur Laufzeit lade ich eine Plug-in-DLL und verwende reflection, um eine Liste aller Typen zu erhalten, die von Entity
abgeleitet sind. Zum Beispiel:
Dann retreive ich eine Liste ihrer Instanzen von DB
%Vor% Entities
ist ItemsSource
des DataGrids, aber was ist der beste Weg, um die Eigenschaften an die DataGrid
zu binden?
Da die Eigenschaften komplex sein können, muss ich auch in der Lage sein, an einen bestimmten Pfad zu binden, zum Beispiel Address.HomeNum
...
Ich muss nur ein Raster der Instanzen eines Typs gleichzeitig anzeigen. Das vollständige Szenario ist dies:
Entity
von der Plug-in-DLL durch Reflektion A
und B
A
, bekomme ich eine Liste von A
Instanzen von DB - so weit so gut. A
in in DataGrid
anzeigen. B
), erhalte ich eine Liste von B
's Instanzen aus der Datenbank und muss diese im Grid anzeigen usw. . Die Plug-in-DLL ist eine Klassenbibliothek ohne XAMLs (auch meine Benutzer sind diejenigen, die diese Plugins machen und ich möchte nicht, dass sie DataTemplate
s für ihre Entitäten schreiben müssen.
Ich kann auch nicht vordefiniert DataTemplate
s machen, da ich nicht die Typen kenne, die ich bis zur Laufzeit anzeigen muss. Jeder Typ kann unterschiedliche Typen und Mengen von Eigenschaften haben. Alles, was ich in der Complie-Zeit weiß, ist, dass sie alle von Entity
abgeleitet sind.
Da Sie die Eigenschaftsnamen der Entitäten vorher nicht kennen, denke ich, dass Sie Ihr DataGrid am besten in Xaml behalten, aber die Definition und die Bindings seiner DataGridColumns in den Code dahinter verschieben.
%Vor% Wenn Sie jetzt diese ausführen, werden Ihre dataGrid-Spalten gefüllt. und indem alle Instanzen des gewünschten Typs in einer beobachtbaren Sammlung hinzugefügt und an ItemsSource des DataGrids gebunden werden, sollte es funktionieren. selectedItem sollte eine Instanz von einer der von Entity abgeleiteten Klassen sein. Das Listenfeld enthält new A()
und new B()
(oder vorhandene Instanzen von A und B), so dass selectedItem in der folgenden Anweisung verwendet werden kann.
wie man DataGridColumnTemplate in schreibt Code
Bearbeiten:
Member kann in diesem Szenario nicht verwendet werden, da INotifyPropertyChanged beteiligt sein sollte. Daher habe ich Member durch Eigenschaften ersetzt.
A DataGrid
scheint in diesem Fall unpassend. Wenn Ihre Liste an zwei separate Entitäten gebunden wäre, würde sie schlecht funktionieren.
Eine bessere Option wäre möglicherweise die Verwendung eines anderen ItemsControl
und die Einrichtung eines DataTemplate
für jeden Typ von Entity
. Auf diese Weise können Sie benutzerdefinierte Editoren für jede Entität erstellen und eine "Liste" von Editoren zum Bearbeiten erstellen.
Wenn Sie wissen, dass die Entitäten immer von einem einzigen Typ sind, würde ich stattdessen die Sammlung dieses spezifischen Typs erstellen und an sie binden.
Ich würde Attribute verwenden, um anzugeben, was genau bindbar ist (einschließlich zusammengesetztes Objekt):
%Vor%Dieses Attribut unterstützt sowohl einfache als auch zusammengesetzte Strukturen. Sie sollten die Methode einfach erben und implementieren.
EntityColumn repräsentiert einen einzelnen Wert. Die vereinfachte Version kann wie folgt implementiert werden:
%Vor%Später können Sie ein einzelnes DataTemplate für EntityColumn erstellen und für alle Eigenschaften für alle möglichen Entitäten verwenden. Entity Object enthält eine zusätzliche Methode, um alle EntityColumn, die relevant sind, zurückzugeben:
%Vor%Für die Sammlung von Entitäten können Sie EntityCollection einführen, das Spalteninformationen absorbiert und eine ähnliche Struktur wie DataSet bietet. Diese Implementierung gibt Ihnen Flexibilität der dynamischen Struktur und hält fast alles stark typisiert. Sie können Attribute und EntityColumn sogar erweitern, um die Validierung zu unterstützen.
Zum Anzeigen eines Objekts sollten Sie lieber ItemsControl oder sogar ein selbst geschriebenes Steuerelement verwenden, das von ItemsControl geerbt wurde, um die Kenntnis von Entity- und EntityCollection-Klassen zu nutzen.