.NET GUI

.NET Community für WPF, Silverlight und mehr!
Willkommen bei .NET GUI. Anmeldung | Registrieren | Hilfe | Impressum | Forumsregeln
in Suchen

Array mit TablePanelLayout

Letzter Beitrag 12-22-2008 14:38 von moe. 6 Antworten.
Seite 1 von 1 (7 Treffer)
Beiträge sortieren: Zurück Weiter
  • 12-17-2008 16:17

    • moe
    • Top 25 Mitwirkender
      Männlich
    • Registriert am 12-17-2008
    • Ulm
    • Beiträge 34
    • Punkte 470

    Array mit TablePanelLayout

    Hallo zusammen.

    Seit längerem arbeite ich schon an folgendem Problem:

    Ich habe eine lokale DB (.sdf) bei mir, um via Windows Forms mir in der DB stehende Formulare anzeigen zu lassen, sprich in der DB stehen die einzelnen Komponenten des mir anzuzeigenden Formulars! Nun ist es so, dass einige Formulare beim laden eine ziemliche Zeit in Anspruch nehmen (bis zu 15 Sek). Das Formular wird auf ein TablePanelLayout gelegt (Elementweise) und danach angezeigt. Die Vorgangsweise dabei ist folgende:

    --> Anfrage an DB "das Formular"

    --> DataTable mit meinen anzuzeigenden Formularelementen wird zurück gegeben (im Extremfall ca 300 Elemente = DataTable rows)

    --> Dieser wird durchlaufen und eben Element für Element mein TablePanelLayout gefüllt

    --> wenn Ende des DataTables erreicht ist wird das TablePanelLayout auf mein Fensterchen gelegt und angezeigt

    Um beim wiederaufruf des Formulars die Ladezeit zu umgehen/beschleunigen würde ich gerne das TablePanelLayout temporär abspeichern und kann es dann so recht fix wieder darstellen (einfaches Auswechseln des aktuellen mit dem gespeicherten TableLayoutPanel auf meinem Fensterchen)...! Was dabei eben so lange dauert ist das einzelne setzen der Elemente auf das TablePanelLayout (for-Schleife).

    Kann ich ein TablePanelLayout mehrdimensionales Array anlegen? Bzw wie kann ich das Problem anderst umgehen um lästige Ladezeiten zu verringern?

    Meine Vorstellung dabei war sowas wie:

    private TablePanelLayout tplArray[']['] = null;

    private int arrayDimensonX = 0;

    private int arrayDimensonY = 0;

    // später im Code dann setzen des "arrayDimenson"-Wertes und Initialisierung des Arrays

    tplArray = new TablePanelLayout()[arrayDimensionX][arrayDimensionY];

    Bei dieser Vorgehensweiße bekomme ich leider schon beim Compilieren diesen Fehler: "Cannot apply indexing with ['] to an expression of type 'System.Windows.Forms.TableLayoutPanel'"

    Scheint also so, als könnte ich gar kein Array vom Typ TableLayoutPanel anlegen?!?! Vllt läuft auch nur das initialisieren falsch? Ist die Schreibweise mit den [']['] richtig oder ist die [,']-Schreibweise die Richtige?

    Für alternative Lösungen wäre ich natürlich auch dankbar :)

     

    noch ein kleiner Hinweis: die ' in den ['] gehören nicht hin, aber ohne den ' hätte es mir die "eckige Klammer zu" nicht angezeigt!

    • Beitragspunkte: 20
    • IP-Adresse ist Registriert
  • 12-17-2008 17:49 Antwort zu

    • Norbert Eder
    • Top 10 Mitwirkender
      Männlich
    • Registriert am 04-09-2008
    • Graz / Austria
    • Beiträge 980
    • Punkte 14.949
    • ForumsAdministrator

    AW: Array mit TablePanelLayout

    Wenn ich dich richtig verstehe: Du lädst aus der Datenbank nicht nur die Daten, sondern auch die Elemente, die in deinem TableLayoutPanel dargestellt werden sollen bzw. zumindest deren Definition? Oder was genau wird da alles geladen?
    • Beitragspunkte: 20
    • IP-Adresse ist Registriert
  • 12-18-2008 12:31 Antwort zu

    • moe
    • Top 25 Mitwirkender
      Männlich
    • Registriert am 12-17-2008
    • Ulm
    • Beiträge 34
    • Punkte 470

    AW: Array mit TablePanelLayout

    genau, in der DB steht eigentlich die Formulardefinition zB sowas wie: Formular 1 hat die Elemente 1 und 2. Element 1 ist ein Label und hat die Größe und die x-y-Position; Element 2 ist eine Textbox und hat die und die Größe und steht auf x-y.
    • Beitragspunkte: 20
    • IP-Adresse ist Registriert
  • 12-20-2008 15:08 Antwort zu

    • Norbert Eder
    • Top 10 Mitwirkender
      Männlich
    • Registriert am 04-09-2008
    • Graz / Austria
    • Beiträge 980
    • Punkte 14.949
    • ForumsAdministrator

    AW: Array mit TablePanelLayout

    Der Zusammenbau deines Panels selbst scheint ja zu funktionieren. Daher speicherst du diese am besten nicht in einem Array, sondern in einer Liste. Abhängig davon wieviele derartiger Panel du hast, kannst du diese ja bei Programmstart laden und hast sie dann immer wieder zur Verfügung.

    • Beitragspunkte: 20
    • IP-Adresse ist Registriert
  • 12-22-2008 10:47 Antwort zu

    • moe
    • Top 25 Mitwirkender
      Männlich
    • Registriert am 12-17-2008
    • Ulm
    • Beiträge 34
    • Punkte 470

    AW: Array mit TablePanelLayout

    soweit sogut... danke hierfür
    Performancetechnisch auf jeden Fall eine Beschleunigung sichtbar/merkbar, NUR (wär ja schön, wenn es keine bugs gäbe...) tritt jetzt das Problem auf, dass wenn ich das Panel abspeicher in meiner Liste und ich es wieder aufrufe, dann seh ich nur einen Teil des Formulars!!

    kurze Situationsbeschreibung:
    Ich habe eine Anwendung, deren Fenster 2-geteilt ist in eine linke und eine rechte Seite! In der Linken habe ich einen TreeView aus dem ich meine Formulare auswählen kann. Diese Formulare werden dann im rechten Fensterteil angezeigt. Wie schon erwähnt habe ich teilweise sehr große Formulare, also muss bei diesen großen Formularen ein Scrollbalken am rechten Rand zu sehen sein; beim normalen erstellen und laden(auf meine alte langsame Art) des Formulars kein Problem und alles ist in Butter, wenn ich das Formular aber abänder(Text in Textboxen oder Checkboxen aktiviere/deaktiviere...) und dann abspeichern klicke, wird es in meine Liste gelegt und beim erneuten Aufruf dieses Formulars wird es(wie gewollt) dann nicht mehr aus der DB geladen und "neu gezeichnet" sondern aus der Liste gezogen auf mein Panel gelegt und angezeigt... und GENAU HIER beim Anzeigen des Formulars aus der Liste wird nur der mir "zuletzt sichtbare Teil des Formulares" angezeigt, OHNE Scrollbalken; um es besser zu beschreiben: Der "zuletzt sichtbare Teil" sieht so aus, als hätte ich einen Bildschirmprint gemacht und genau der wird mir dann angezeigt. Wenn ich mich also im "Vollbildmodus" befinde, wird mir mehr vom Formular angezeigt, wie wenn ich mein Applikationsfenster auf zB einer Größe von 640*480 hätte!!!
    Eigenschaft des Panels auf das ich das Formular lege ist auf AutoSize = true und AutoScroll = true;
    • Beitragspunkte: 20
    • IP-Adresse ist Registriert
  • 12-22-2008 13:31 Antwort zu

    • Norbert Eder
    • Top 10 Mitwirkender
      Männlich
    • Registriert am 04-09-2008
    • Graz / Austria
    • Beiträge 980
    • Punkte 14.949
    • ForumsAdministrator

    AW: Array mit TablePanelLayout

    Vielleicht solltest du ein paar deiner relevanten Sourcecode-Stellen zeigen, damit wir ein Bild davon bekommen, was du genau machst. So ist es etwas schwierig dein Vorgehen nach zu vollziehen.
    • Beitragspunkte: 20
    • IP-Adresse ist Registriert
  • 12-22-2008 14:38 Antwort zu

    • moe
    • Top 25 Mitwirkender
      Männlich
    • Registriert am 12-17-2008
    • Ulm
    • Beiträge 34
    • Punkte 470

    AW: Array mit TablePanelLayout

    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)formularListFLPIdea;
                    if (flp.Tag.Equals(instance_id.ToString()))
                        flowpanel = (FlowLayoutPanel)formularListFLPIdea;
                }

                // try to find existing formular --> grid
                for (int i = 0; i < formularListTLP.Count && flowpanel == null && gridpanel == null; i++)
                {
                    TableLayoutPanel tlp = (TableLayoutPanel)formularListTLPIdea;
                    if(tlp.Tag.Equals(instance_id.ToString()))
                        gridpanel = (TableLayoutPanel)formularListTLPIdea;
                }


    // 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
    Tongue Tied


    • Beitragspunkte: 5
    • IP-Adresse ist Registriert
Seite 1 von 1 (7 Treffer)
Powered by Community Server (Commercial Edition)    69° - Internet-Agentur München (CMS, ASP.NET, Webdesign)