Strukturierung einer Form -------------------------------------------- Beispiel
Wie in der Abb. zu sehen, wird es sehr schnell komplex. Dort sind sehr viele Funktionalitäten beisammen.
Z.B. das Zusammenspiel der Radio-Buttons, welche bei der Buchführung Ein- und Ausgaben unterscheiden, dabei den MWSt-Satz automatisch erzeugen.
Für den Fall, daß die Automatik ausgeschaltet wird, muß die Zuweisung an Konto oder Gegenkonto geklärt sein.
Darüber hinaus ist eine Liste abrufbar, in der sich ständig wiederholende Buchungen befinden. Wenn man also einen Leasing-Vertrag bedient, wählt man den hier aus und die Buchung ist mit einem Click erledigt.
Für die Konten gibt es eine Filter-Funktion (hier nicht angeklickt) mit Kontenklassen oder nach Alphabet.
Daneben muß der Buchungssatz geprüft werden auf logische Konsistenz und wenn das erfolgt ist, die Option Speichern (hier nicht sichtbar) sichtbar gemacht werden. Sie ist hier nicht sichtbar, weil zuerst der Datensatz übernommen werden muß, dazu wird er zuvor geprüft.
Und so weiter und so fort. Davor hängen natürlich Datei-Lesezugriffe, dahinter Speicherzugriffe, und die Listboxen müssen erstmal aufgefüllt und ständig aktualisiert bzw. sortiert werden. So eine kleine Form kann schon eine Menge Holz bedeuten.
Was mit einem kleinen Formular anfängt, wird SEHR SCHNELL UNÜBERSICHTLICH, insbesondere die Rückbezüglichkeiten innerhalb der Windows-Click-Welt können sehr große Probleme erzeugen, wenn man das nicht von Anfang an, sozusagen gnadenlos, klar strukturiert.
Klar gibt es beim Programmieren keine rote Linie. Es ist alles sehr individuell.
Ich will hier trotzdem ein paar Tipps geben, wie man in der Windows Welt die Übersicht behält in dem Sinne, daß ständige spätere Erweiterungen das Formular nicht vermüllen.
Leider gibt es keine (sinnvolle) Möglichkeit, den Zugriff auf die Elemente einer Form von außen zu steuern, z. B. durch eine Klasse. Die Anweisungen für das, was sichtbar gemacht werden soll, textBox, listBox, Button etc. etc., müssen sich im Formular befinden. Man kann das nicht auslagern. Und so wird das Formular immer länger und länger und länger ..... Vorgeschlagene Struktur:
FormSonstwas (Windows Form)
public partial class formName : Form // Parent der Mutterklasse Form
{
BLOCK 1: formName() // der Konstruktor
{
initializeComponent();
// hier gehören alle Anweisungen rein, die beim Aufruf des Formulars einmalig ausgeführt werden müssen
// i.d.R. werden das die Initialisierung von Daten sein, die z. B. aus Dateien ausgelesen werden
}
BLOCK 2:// Hier eine Generalmethode zur Abhandlung aller Ereignisse innerhalb der Form:
private void Generalmethode(object sender)
{
// die kann anhand des Parameters sender feststellen, wer wo wie was geklickt hat
// und sich ihren Reim darauf machen, was nun zu tun ist
}
BLOCK 3://Nun müssen wir die Ereignishandler der Buttons, Radiobuttons, Listboxen etc. etc. unterbringen
// Das gibt je nachdem eine lange, lange Liste, daher umso wichtiger, daß man alles zusammenfaßt
// möglichst sortiert nach Art der Elemente
// was sollen wir da reinschreiben?
// erstmal nur den Aufruf der Generalmethode, sonst gar nichts:
private void btTuDies_Click(object sender, EventArgs e)
{
Generalmethode(this.btTuDies); // Aufruf der Generalmethode, sonst erstmal gar nichts
}
private void btTuDas_Click(object sender, EventArgs e)
{
Generalmethode(this.btTuDas);
}
private void listBoxDatensonstwas_DoubleClick(object sender, EventArgs e)
{
Generalmethode(this.ListBoxDatensonstwas);
}
// Alle diese Elemente melden also, daß sie aufgerufen werden, und machen sonst erstmal gar nix
BLOCK4:// Nun folgt eine noch längere Aneinanderreihung von allen Methoden, welche die Generalmethode benötigt, um übersichtlich zu bleiben
// Z. b. in einer Datei irgendeinen Datensatz finden, gehört in einer Unterfunktion (Methode), die hier zu finden ist
private void SucheXy()
{
}
private double Suche Kontonummer(string Listboxstring)
{
}
}// Schlußklammer der partial formName
}// Schlußklammer Namespace
Wir haben dadurch unsere Form, die leider Gottes sehr sehr lang werden wird, immerhin in 4 Blöcke strukturiert, die bei der Übersicht enorm helfen.
Eine interessante Frage ist, wieviel Funktionalität die Elemente über diejenige hinaus bekommen sollen, daß sie der Generalmethode schlicht melden, angeklickt worden zu sein?
Meine Empfehlung wäre: so wenig wie möglich. Soviel wie nötig erscheint, ist bei genauerer Überlegung selten bis nie nötig. Im Grunde brauchen diese Buttons keine Funktionalität. Der Grund ist, daß beim Ausbau des Programms sehr leicht Zirkelschlüsse auftreten, Werte werden geändert, ohne daß man weiß, wo es herkommt. Läßt man die Buttons dumm, können die einem nicht dazwischenfunken, und man erfüllt das Paradigma der OOP auch innerhalb der Klasse: Datenkapselung soviel wie möglich, Späte Bindung.
Die Datenübergabe zwischen Klassen und Forms, hin und zurück:
Da wird ein großes Bohei gemacht, wie sich die Forms und Klassen untereinander mitteilen sollen oder können oder dürfen.
Wenn z. B. die Form3, aufgerufen durch Form2, welche durch Form1 aufgerufen wurde, feststellen würde, der geplante Vorgang läßt sich so nicht ausführen, wie soll dann die Rückmeldung erfolgen?
Oder wenn die Form3 dann noch eine Funktion einer Klasse aufruft, und erst diese die Feststellung macht, wie soll der Informationsfluß zurück erfolgen?
Wie sollen die nachgeordneten Forms und KlassenMethoden überhaupt feststellen, welche Parameter erforderlich sind für die angeforderte Methode?
In welche Datenstrukturen sollen sie ihre Informationen hineinschreiben, wenn diese Datenstrukturen gekapselt sind?
Viele Fragen, und ja, jedes Programm ist anders und eine generelle Lösung für alles gibt es nicht.
Um diese ganze Kasperei um diese Dinge aber mal aufzubrechen: die Lösung ist sehr einfach.
Wir können eine Klasse definieren, auf die alle Klassen und Forms einen Zugriff haben
(BITTE NICHT UMGEKEHRT, dann gibt es Zirkular-Referenzen),
also eine Klasse, die ich als das Schwarze Brett bezeichnen möchte,
in der alle Klassen ihre Nachrichten hinterlassen.
Die Klasse macht man am besten static, damit nicht verschiedene Instanzen zur Verwirrung führen.
Z.B. nennen wir diese Klasse mal
public static class REGISTER
{
}
Sie enthält sozusagen Flags über den Zustand des Programms, die man mit get/set auch noch kapseln kann, wenn man will.
Ein Beispiel wäre die fortlaufende Numerierung von Datensätzen, welche in verschiedenen Forms und Klassen bearbeitet werden müssen. Nehmen wir einen Datensatz hinzu, muß die Numerierung um 1 erhöht werden. Die entsprechende Datei oder Liste kann aber von den nachgeordneten Forms und Klassen gar nicht ausgelesen werden (private). Woher nimmt nun eine Methode, aufgerufen von der Form3, diese Information, die nur in der Form2 verfügbar ist?
Ganz einfach:
Form2 teilt der public static class REGISTER mit, daß
public long IDENTNR einen bestimmten Wert hat. Wie der zustande gekommen ist, weiß nur die Form2, weil sie Zugriff auf die entsprechende Datei hat, die Form 3 weiß es nicht.
Aber nimmt die Form3 mit einer Methode einen Datensatz auf, kann sie durch Zugriff auf die Klasse REGISTER den richtigen Wert entnehmen (und den Zähler anschließend um 1 heraufsetzen, gehört sich ja so, bzw. kann man das in der Methode auch automatisch implementieren, daß beim Zugriff auf den Getter der Setter den Wert um 1 nach oben setzt).
So daß dann, wenn irgendeine Form oder Methode einen Datensatz hinzufügen will, dasselbe verfügbar ist.
Der Beitrag wurde von sharky2014 bearbeitet: 25.04.2014, 16:04 Uhr
Angehängte Datei(en)
formular.jpg ( 313.54KB )
Anzahl der Downloads: 11