C# 3 Listen, 3 DataGrids, Verknüpfungen schaffen

Mijay

Ensign
Registriert
Apr. 2010
Beiträge
160
Hallo zusammen,

und mal wieder ich mit einer nächsten Frage zu den tollen DataGrids (in der Firma kann mir leider keiner etwas dazu sagen, da die damit nie gearbeitet haben).

Ausgangslage
- 3 Listen (List<T>, gefüllt mit Objekten(Häusern (Attribute Ort und Hausnummer) und Personen (Attribute Vorname, Nachname, Alter))
- 3 DataGridViews (hinter jedem DataGrid befindet sich je eine der Listen mit Objekten)

Ich werde probieren mein Problem anhand von Häusern und Personen zu beschreiben.
1. DataGridView = Datenpool von Personen-Objekten (dort werden alle Personen aus unterschiedlichen Quellen ermittelt und die Attribute dargestellt)
2. DataGridView = Häuser (dort werden die ermittelten Häuser dargestellt mit den Attributen)
3. DataGridView = spezifische Personen-Liste

Funktionsweise

Im Datenpool habe ich eine Ansammlung von Personen. Diese kann ich in die spezifische Personen-Liste hinzufügen. Diese spezifische Personen-Liste ist abhängig vom selektierten Haus in DataGrid 2.
Ich bekomme also in DataGrid 3 die Personen zu dem selektierten Haus aus DataGrid 2 angezeigt die ich aus Datagrid 1 (Datenpool) hinzugefügt habe.
Aktuell muss ich eine Verknüpfung zwischen DataGrid 2 und DataGrid3 schaffen (eher von den dahinter liegenden Listen).
Dazu ist mir eine SortedList eingefallen, da ich als Key ein Haus und als Value eine Liste mit spezifischen Personen übergeben könnte. Allerdings habe ich ja auch eine ganze Liste voll mit Häusern und ich weiß nicht ob das dann auch noch funktioniert (dann müsste ich ja so viele SortedLists erstellen wie es Häuser gibt).
Kann man das mit meiner bisherigen Struktur von 3 Listen (und zusätzlichen Listen) realisieren oder muss ich auf etwas komplett anderes umswitchen (obwohl ich heidenfroh bin, dass das jetzt soweit alles mit meinem Listen funktioniert, ohne Verknüpfung allerdings)?

Ziel
Im Endeffekt möchte ich die Daten aus DataGrid 2 in eine Textdatei (ja eine ganz einfache Textdatei mehr ist nicht erforderlich!) schreiben. Das dazugehörige Haus gibt mir u.a. den Pfad an (den ich ermittelt habe), wohin die Textdatei gespeichert werden soll.

Bis jetzt konnte mir hier super geholfen werden und ich hoffe, dass auch dieses Problem auf einfache Weise (ich bin noch nicht sooo vertraut mit C#) gelöst wird.

Gruß
Mijay
 
Zuletzt bearbeitet:
Was mach ich vorerst erstmal interessiert, wie sieht deine Datenstruktur direkt aus?Kannst du mal die Klassen Person/Haus hier posten?Wenn du sagst zu jedem Haus gehören spezifische Personen könnte es sein das du eventuell schon was in der Modellierung falsch gemacht hast und wir dort ansetzen können um dir die View-Gestaltung leichter zu machen.
 
Wegen Datenschutz probiere ich soweit es geht alles zu umschreiben.

Class Haus
private string strOrt = string.Empty
private string strNr = string.Empty

public string Ort
{
get
{
return this.strOrt;
}
set
{
this.strOrt = value;
}
}

für die Nr gilt das Selbe.
Die Klasse Personen ist identisch aufgebaut. Beide haben derzeit keine Methoden.

Ich habe dann eine statische Klasse für die ganzen Listen. In dieser werden die erforderlichen Informationen ermittelt und und in die entsprechende Liste eingefügt.
Auf diese Listen greife ich dann aus, ich nenne diese jetzt UserControl Klasse(darin befinden sich alle Controls), zu und stelle diese in den entsprechenden DataGrids dar.

Zusammenfassend
1. Klasse "Haus"
2. Klasse "Person"
3. Klasse "Listen"
4. Klasse "UserControl"

Die Idee war alles in unabhängige Listen zu speichern und die entsprechenden dann, ich muss es leider sagen, "irgendwie" miteinander zu verknüpfen. Im Prinzip ist das so eine Key Value Geschichte. Ich hatte auch mal an SQL und solche Scherze gedacht, aber das ist alles zu überdimensioniert meine ich.
Im Prinzip sind es 3 Listen, aus einer werden Daten herausgenommen in eine andere geschrieben und zwei Listen sind miteinander verknüpft.
 
Zuletzt bearbeitet:
Du könntest doch einfach deiner Haus - Klasse ne Liste mit den spezifischen Personen hinzufügen.
Wenn dann im "Haus DataGrid" ein Haus Objekt selektiert wird, kannst du die Liste aus dem selektierten Objekt an das "spezifische Personen DataGrid" binden.

ungefähr so:
Code:
public class Haus
{
    public string Ort { get; set; }
    public string Nummer { get; set; }
    public BindingList<Person> SpezifischePersonen { get; set; }
}


private void dgv_häuser_SelectionChanged(object sender, EventArgs e)
{
    if (dgv_häuser.SelectedRows.Count < 1)
        return;

    var haus = (Haus)dgv_häuser.SelectedRows[0].DataBoundItem;
    dgv_spezifischePersonen.DataSource = haus.SpezifischePersonen;
}

PS: Schau dir mal Automatisch implementierte Eigenschaften an, das erspart viel Schreibarbeit.
 
Zuletzt bearbeitet:
okay, was ich jetzt auf die schnelle bei dem Link gelesen habe "In C# 3.0...." ich arbeite aber nur mit 2.0. Gibt es das da auch schon?

edit: ich arbeite mit VisualStudio 2005
 
Zuletzt bearbeitet:
Es funktioniert auch wenn du .net 2.0 als target nimmst, da auto implemented properties ein Compilerfeature sind.
Allerdings ist dieses Feature erst in VS2008 verfügbar.
Kannst ja wie schon gesagt trotzdem mal ausprobieren obs geht ;)
 
@toeffi ich habe hier zu Hause nur VisualStudio 2008 und kein 2005 und deswegen kann ich es hier nicht testen. Nicht, dass im 2008er andere Funktionen zur Verfügung stehen, die ich letztendlich auf Arbeit gar nicht nutzen kann.

Damit es zu keinen Verwechslungen kommt: Ich benutze 3x DataGridView, nicht DataGrid. Ich wusste nicht, dass es überhaupt ein DataGrid gibt...
 
Du kannst mit VS2008 genau so arbeiten wie mit dem VS2005, was es an Funktionalität zusätzlich gibt, liegt an dem .NET Framework. Zudem kannst du das auch noch extra für das Projekt einstellen, welche Libraries genutzt werden sollen, also ob .NET 2.0 oder doch 3.5 bzw. 4.
Das Ding ist nur, wenn du das mit VS2008 öffnest dann kannst du es nicht mehr mit VS2005 bearbeiten, nur mit etwas Mühe. Da müsstest du dann die *.sln Datei etwas anpassen.

Wieso kannst du eigentlich kein höheres Framework nutzen? Ist es auf Arbeit nicht gewünscht?
Was auch geht und Free ist und da sollte es keine Probleme weiter geben ist SharpDevelop.

Kannst du ja mal probieren. ;)
 
Das ist eine vorgegebene Randbedingung bei mir nur mit Framework 2.0 zu arbeiten.
Hier zu Hause würde ich auch nicht die erforderlichen "Personen" Daten ermitteln können, da ich dafür die entsprechenden Quellen nicht zur Verfügung habe.

Wegen dem einstellen des Frameworks, das ist gut zu wissen. Danke :-) Wieder was gelernt.
Ich muss sagen ich lern hier echt ne Menge in dem Forum.
 
Kleine Anmerkung zu den autoimplemented Properties:
Diese gibt es zwar nicht in VS 2005, jedoch wird hier nur ein üblicher getter und setter vom Compiler (ab VS 2008) selber generiert, sodaß man diesen nicht explizit im Code schreiben muss. Also einfach im VS 2005 die Property ausschreiben. Es ist nichts magisches dahinter:

Code:
// statt:
// public BindingList<Person> SpezifischePersonen { get; set; }

// einfach in VS 2005 das hier schreiben:
BindingList<Person> listSpezifischePersonen;
public BindingList<Person> SpezifischePersonen
{
  get { return listSpezifischePersonen;} 
  set { listSpezifischePersonen=value;} 
}

Vie Erfolg!
 
Ich habe das hinzufügen der spezifischen Personen nicht mit einer BindingList gelöst sondern auch mit einer einfachen List. Diese List ist in meinem Hausobjekt.
Ich ermittel mir einfach immer den Index des selektierten Hauses, dann den Index der dahinterliegenden Liste und wenn beide gleich sind habe ich das Objekt gefunden und habe Zugriff auf die "spezifische Personen Liste" des Hauses und stelle diese im DataGrid dar.
Das funktioniert auch alles ohne Probleme und genau so wie es soll.

NUR:
Wenn ich jetzt im Datagrid der "spezifischen Personen" ein Objekt (eine Zeile) mit der Maus oder Tastatur selektiere oder den Header anklicke, kommt immer die Meldung: "Der Index -1 hat keinen Wert".
Ich habe alles durchdebugged und die "spezifische Personen Liste" wird immer richtig mit Objekten gefüllt oder entfernt. Es sind alle Daten vorhanden, nur kommt immer diese dumme Meldung. Derzeit weiß hier keiner woher die kommt...
Ich hoffe, ihr könnt mir da helfen.

edit: Die beiden anderen DataGrids funktionieren ohne Probleme. Ich verstehs einfach nicht, warum dieses DataGrid so viel rumstresst, da es ziemlich identisch zu den anderen ist.

edit2: Fehler endlich gefunden. Ganz doofe Sache. Ich benutze das Event SelectionChanged und da rennt der mir auch ganz am Anfang durch und findet manche Dinge nicht. Wie kann ich dem Event sagen, dass es erst aktiv sein darf, nachdem alles geladen wurde? Gibt es beim Datagrid etwas, dass keine Zelle / Zeile etc. von anfang an auswählt? Wenni ch das ausschalten könnte, müsste mein Problem gelöst sein.
 
Zuletzt bearbeitet:
Bau doch einfach eine Bedingung ein. Sprich: Dein Code soll nur ausgeführt werden, wenn der Index >= 0 ist.

Sieht dann ganz einfach so aus (pseudocode):

Code:
if(Index < 0)
     return;

Dadurch wird dann das Event zwar immernoch aufgerufen, aber dein Code nicht, da die Ausführung abgebrochen wird, falls der Index "out of range" ist.

Du könntst natürlich das Event erst dann abonnieren, wenn deine Listen ordnungsgemäß gefüllt sind, was aber imo umständlicher ist, als erstere Lösung.
 
Das Event selbst kannst du unterdrücken. Jedoch ist das nicht wirklich sinnvoll, deshalb besser die von Grantig beschriebene Lösung gehen.

Allgemein gesprochen: Es wäre gut, wenn du deinen Code mal reviewst und entsprechend diese Sachen abprüfst. Das Problem ist nicht gerade unüblich, das ein Index den Wert -1 hat. Das passiert oft beim Programmstart, weil Objekte nicht oder nicht vollständig initialisiert sind, aber auch während des normalen Betriebs, wenn mal eine der vielen möglichen Randbedingungen dazu führt. Erwarte im .Net niemals, dass alle Objekte zu jedem Zeitpunkt verfügbar sind. Nur weil du im Code eine Variable hast/verwendest, bedeutet es nicht, dass diese auch immer auf ein gültiges Objekt verweist.

Viel Erfolg...
 
Zurück
Oben