Könntest du beim nächsten Mal bitte
nur die notwendigen Schnipsel einfügen?
Wegen diesen 2 hingeschluderten
kompletten Dateien wollte ich hier eigentlich nichts antworten...
Zum Problem:
Du solltest deinen Code style und deine Herangehensweise von Delphi auf .Net umstellen.
- C# hat einen multi pass compiler, d.h.: du kannst problemlos deine Klasse Person nehmen und in eine eigene Datei packen.
- Nested classes sollten nur private/protected sein. Um Ordnung zu waren sind namespaces da.
- Üffentliche felder sollten höchtens für value types (struct) verwendet werden, sonst Properties. (z.b.: ohne Properties, kein DataBinding )
Da .Net 2.0 vor der Tür steht[meta]Release am 7.11.[/meta], werde ich nur auf das VS2005 eingehen. (Die Beta von C# Express kannst du noch bei MS saugen)
Ich habe deine Person so geändert:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60:
| public class Person { int id; string name; string firstName; DateTime birthDate; string clan; double won; double lost; double percentage;
public int Id { get { return id; } set { id = value; } } public string Name { get { return name; } set { name = value; } } public string FirstName { get { return firstName; } set { firstName = value; } } public DateTime BirthDate { get { return birthDate; } set { birthDate = value; } } public string Clan { get { return clan; } set { clan = value; } } public double Won { get { return won; } set { won = value; } } public double Lost { get { return lost; } set { lost = value; } } public double Percentage { get { return percentage; } set { percentage = value; } }
public override string ToString() { if (!string.IsNullOrEmpty(firstName)) return string.Format("{0}, {1}", name, firstName); else return name; } } |
Das Ganze einmal kompilieren.
Nun kannst du im Menü unter Dataßadd new DataSource deine Person auswählen um sie für den Designer sichtbar zu machen.
In der DataSorces Ansicht siehst du nun deine Person und kannst sie auf dein Form ziehen. Dabei wird ein vorkonfigurierter DataGridView eine BindingSource und ein BindingNavigator angelegt.
Lege nun ein nuees Form an[meta]bleiben wir ruhig bei Form1 und Form2...[/meta].
In den DataSources-Übersicht änderst du die Ansicht von Person indem du auf den DropDown button klickst.
Du kannst nun vom Grid auf Details wechseln[meta]sieht ähnlich aus wie ein Form icon[/meta].
Jetzt ziehst du wieder deine Person auf die Form und hast für jede Property ein passendes Control sowie ein Label.
Den Navigator brauchen wir hier nicht, den kannst du einfach löschen.
Sicherheitshalber jetzt alles speichern.
nun noch die üblichen OK/Cancel buttons[meta]für den DialogResult[/meta] und wir können in den Code wechseln.
Wir fügen eine öffentliche Eigenschaft hinzu, um von außen eine Person an die bindingSource zu hängen, bzw. auszulesen. Aus Einfachheit gleich noch einen constructor, der diese Eigenschaft vorbesetzt:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| public Form2() { InitializeComponent(); }
public Person Person { get { return personBindingSource.DataSource as Person; } set { personBindingSource.DataSource = value; } }
public Form2(Person person) : this() { Person = person; } |
Nun noch deine 2 ButtonClick handler[meta]Darin _nur_ DialogResult bestzen[/meta] und das war's für Form2.
Speichern (nicht vergessen: Beta
)
Zu Form1:
Hier haben wir ja bereits unseren DataGridView (DGV) und die BindingSource (BS) bzw den Navigator (BN).
Wenn der User eine neue Person anlegt, soll sich das Form2 öffnen so dass er darin die Daten eingeben kann.
Die DGV sollte also so geändert werden, dass darüber keine neuen Personen angelegt werden können. Einfach draufklicken und oben links im Smart Tag das Hinzufügen deaktivieren.
Damit wir das Hinzufügen im BN selbst behandeln können schalten wir die Standard funktion dafür ab. Im Property View findest du unter Items "AddNewItem", setze das auf null.
Nn können wir mit dem Button[meta]der, der aussieht wie ein gelber Stern[/meta] machen was wir wollen.
Also: Doppelklick auf den ToolButton in der TooolBar vom Navigator.
Wir erzeugen eine neue Person, übergeben sie dem constructor von Form2 und führen es als modalen Dialog aus.
Wenn der User OK angeklickt hat kommt die Person in die BS. Das using verhindert ein MemLeak, da modale Dialoge kein Dispose in Close ausführen.
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| void bindingNavigatorAddNewItem_Click(object sender, EventArgs e) { Person person = new Person();
using (Form2 dialog = new Form2(person)) { if (dialog.ShowDialog() == DialogResult.OK) { personBindingSource.Add(person); } } } |
Oh eins noch, wo wir gerade im Code sind...
Die BS enthält ja noch kein Objekt als DataSource.
Im Form2 haben wir nur eine einzelne Person gehbt, hier in form1 haben wir aber eine Liste von Personen.
Dafür bietet sich eine BindingList[meta]Für die Suche in der Doku: System.ComponentModel.BinindList bzw IBindingList[/meta].
Die Liste übergeben wir der BS einfach direkt im constructor[meta]wichtig: _nach_ InitializeComponents[/meta]:
C#-Quelltext
1: 2: 3: 4: 5: 6:
| public Form1() { InitializeComponent();
personBindingSource.DataSource = new BindingList<Person>(); } |
Das war's schon.
Ich habe eine Details Ansicht noch neben die DGV gepackt und einen Screenie gemacht.
Mag zwar alles im 5. Gang runtergerasselt worden sein, aber
- für jeden unklaren Begriff gibt es die ausführliche .Net SDK Doku und
- dürftest du beim Durchgegehn der Schritte[meta]immer schön mit der Doku[/meta] ganz schnell auf den Trichter kommen
.
_Eigentlich_ hättest du Person nur als öffentliche Klasse deklarieren und eine Instanz dem Form2 übergeben müssen. Da ich aber gerade Lust hatte ist dann doch noch etwas DataBinding á la .Net2.0 draus geworden.
Da im Code ausschließlich gegen die BS geschrieben wurde, kannst um Design machen was immer du willst. Zum Beispiel den DGV gegen eine ComboBox, ListBox oder ein DataGrid oder die Controls in Form2 gegen andere tauschen. Ist vollkommen Bohne. Und alles ohne ekliges DataSet.