ja, dann will ich das doch mal versuche. leider ist das nicht so einfach vor lauter verschiedener methoden usw... deswegen werde ich das nötigste hier posten bei knapp 4k zeilen code also nicht gerade soooo wenig ;-)
Das hier ist der Inhalt der Methode zum Darstellen der Formulare(vorher noch ein kleiner Hinweis bezüglich der Variablen):
- rot markierte stellen sind, so denke ich, schlüsselstellen; blaue stellen sind kommentare; schwarze stellen sind code!
- dbConnect --> Meine Datenbankverbindung - eigene klasse;
- formularListFLP --> als "List<FlowLayoutPanel>" deklariert
- formularListTLP --> als "List<TableLayoutPanel>" deklariert
- instance_id --> die eindeutige Kennung meines Formulares(Beziehung zwischen Kundeninformationen und Formular werden dort hergestellt, da das gleiche Formular auch bei anderen Kunden angewendet werden kann)private void showForm()
{
// load formular elements
DataTable elementsTable = dbConnect.ElementsByInstance(instance_id);
string layoutType = dbConnect.layoutTypeByInstance(instance_id);
plusclick = 0;
int colNo = 0;
int rowNo = 0;
int maxCols = 0;
int maxRows = 0;
FlowLayoutPanel flowpanel = null;
TableLayoutPanel gridpanel = null;
// das ist jetzt der neue ansatz, ich gehe durch meine (global deklarierte liste, da zwei layout typen - grid und flowlayout - auch zweierlei listen)
// falls eine übereinstimmung anhand der instance_id gefunden wird wird das jeweilige panel belegt. // try to find existing formular --> flow
for (int i = 0; i < formularListFLP.Count && flowpanel == null && gridpanel == null; i++)
{
FlowLayoutPanel flp = (FlowLayoutPanel)formularListFLP
;
if (flp.Tag.Equals(instance_id.ToString()))
flowpanel = (FlowLayoutPanel)formularListFLP
;
} // try to find existing formular --> grid
for (int i = 0; i < formularListTLP.Count && flowpanel == null && gridpanel == null; i++)
{
TableLayoutPanel tlp = (TableLayoutPanel)formularListTLP
;
if(tlp.Tag.Equals(instance_id.ToString()))
gridpanel = (TableLayoutPanel)formularListTLP
;
}// wenn ich das formular zum ersten mal aufrufe oder keine übereinstimmung gefunden wurde wird das formular geladen(code zwischen den zwei grünen doppelten strichen)
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
if (gridpanel == null && flowpanel==null)
{
// initializing shared controls
Button btnSaveNext = new Button();
// setting atributs for the "save" button
btnSaveNext.Name = "btnSave";
btnSaveNext.Text = "Save / Next";
btnSaveNext.Click += new EventHandler(btnSaveNext_Click);
// check for the layout Type and create a FlowLayoutPanel for "vflow" or a TableLayoutPanel for "grid"
if (layoutType == "vflow")
{
flowpanel = new FlowLayoutPanel();
// init flowpanel
}
else if (layoutType == "grid")
{
gridpanel = new TableLayoutPanel();
maxCols = Convert.ToInt32(dbConnect.maxColsByFormID(form_id));
maxRows = Convert.ToInt32(dbConnect.maxRowsByFormID(form_id));
// initialize the grid panel
gridpanel.Name = "gridpanel";
gridpanel.RowCount = maxRows;
gridpanel.ColumnCount = maxCols + 1;
gridpanel.CellBorderStyle = TableLayoutPanelCellBorderStyle.Single;
gridpanel.Dock = DockStyle.None;
gridpanel.AutoSize = true;
gridpanel.AutoSizeMode = AutoSizeMode.GrowAndShrink;
gridpanel.AutoScroll = false;
gridpanel.Tag = instance_id.ToString();
} // indicator for repeatable lines
int repeatableLine = 0;
// checkbox panel
FlowLayoutPanel tempCheckBoxPanel = null;
// run through the elements of the form
for (int j = 0; j < elementsTable.Rows.Count; j++)
{
int elementID = Convert.ToInt32(elementsTable.Rows[j]["form_element_id"]);
string fieldtype = elementsTable.Rows[j]["element_type_name"].ToString();
if (layoutType.Equals("grid"))
{
colNo = Convert.ToInt32(elementsTable.Rows[j]["element_hpos"]);
rowNo = Convert.ToInt32(elementsTable.Rows[j]["element_vpos"]) - 1;
// if there is a repeatable line on the formular add a plus button
if (elementsTable.Rows[j]["vpos_repeatable"] != DBNull.Value && elementsTable.Rows[j]["vpos_repeatable"].ToString().Equals((rowNo + 1).ToString()) && maxCols == gridpanel.ColumnCount - 1)
{
gridpanel.ColumnCount++;
gridpanel.Controls.Add(btnPlus, 0, rowNo);
}
}
// nochmals der hinweis, hier habe ich den code absichtlich nicht gepostet, im endeffekt ist es aber recht einfach erklärt: je nachdem welchen "fieldtype" ich habe lade ich das dementsprechende element; date, email, number, tel usw sind nur normale textboxen, nur mit jeweils anderem regex-ausdruck zur validierung!! switch (fieldtype)
{
case "label":
{ } break;
case "text-singleLine":
{ } break;
case "text-multiLine":
{ } break;
case "date":
{ } break;
case "text-email":
{ } break;
case "text-number":
{ } break;
case "text-tel":
{ } break;
case "text-ip":
{ } break;
case "bool":
{ } break;
} // end building controls
}
// adding the "save/next" button at the end of the layout panel
btnSaveNext.Name = instance_id.ToString();
// add "save / next" button on panel
if (layoutType.Equals("vflow"))
flowpanel.Controls.Add(btnSaveNext);
else if (layoutType.Equals("grid"))
gridpanel.Controls.Add(btnSaveNext, 1, gridpanel.RowCount + 1);
// get number of repeatable element ---> formulare können durch betätigen eines "+"-buttons erweitert werden(eine in der DB stehende formular definierte zeile wird nochmals geladen und dem gridpanel hinzugefügt) int repeatableElementCounter = db.getMaxFormDataTag(instance_id);
// add repeatable elements
for (int i = 0; i < repeatableElementCounter; i++)
gridpanel = loadRepeatableLine(repeatableLine, gridpanel, elementsTable, i + 1);
}
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// set the current treenode as saved node ---> um bei n-maligem anklicken des gleichen treenodes ein ständiges formularladen zu verhindern(überprüfung im eventhandler vom treenode!!!)
lastSelectedTreeNode = treeViewProjects.SelectedNode;
// add panel on container
// hier das von mir erwähnte geteilte fenster --> je nach layouttyp wird das dementsprechende panel auf das panel des rechten fensters gelegt und angezeigt! if (layoutType == "vflow")
splitContainer.PanelRight.Controls.Add(flowpanel);
else if (layoutType == "grid")
splitContainer.PanelRight.Controls.Add(gridpanel); }
die Methode zum Speichern eines Formulares (eventhandler des SaveNext buttons --> btnSaveNext_Click()) kann ich mir im großen und ganzen sparen. da heißt es nur: das angezeigte formular auf vollständigkeit checken, eingabefelder validieren und wenn alles passt die daten in die DB schreiben, DAS AKTUELL ANGEZEIGTE PANEL SPEICHERN(in liste mit formularListTLP.add(gridpanel) oder formularListFLP.add(flowpanel)), und das nächste formular anzeigen!
ich hoff das reicht um es etwas zu verdeutlichen