WPF: Die beste Methode zum Erstellen von Bindungen zu unbekannten Typen in MVVM

8

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:

%Vor%

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 ...

Erläuterungen

  1. Ich muss nur ein Raster der Instanzen eines Typs gleichzeitig anzeigen. Das vollständige Szenario ist dies:

    1. Ich erhalte eine Liste von Typen, die von Entity von der Plug-in-DLL durch Reflektion
    2. abgeleitet sind
    3. Ich zeige ihre Namen in einer Liste. (In diesem Beispiel enthält diese Liste A und B
    4. Wenn der Benutzer auf ein bestimmtes Element klickt, sagen wir A , bekomme ich eine Liste von A Instanzen von DB - so weit so gut.
    5. Ich möchte die Liste der Instanzen von A in in DataGrid anzeigen.
    6. Wenn der Benutzer ein anderes Element aus der Liste auswählt (was einen anderen Typ bedeutet, sagen wir B ), erhalte ich eine Liste von B 's Instanzen aus der Datenbank und muss diese im Grid anzeigen usw. .
  2. 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.

  3. Das Gitter sollte auch editierbar sein.
Omri Btian 30.10.2013, 21:20
quelle

3 Antworten

3

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.

%Vor%

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.

    
Bijan 05.11.2013, 03:17
quelle
5

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.

    
Reed Copsey 30.10.2013 21:24
quelle
0

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.

    
agrinevsky 08.11.2013 20:33
quelle

Tags und Links