Fensterverwaltung

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von GerhardW.

    Fensterverwaltung

    Guten Abend,

    folgendes Problem:

    Zur Zeit gibt es eine Anwendung, welche alle wichtigen Formualre in ein MDI Parent lädt. Dies wird deshalb gemacht, damit die Umschaltung zwischen den Formularen möglichst reibungslos stattfindet.
    Das Problem ist, dass in den Formen viele Controls sind und es für den Benutzer beim neu Laden einer Form eine gewisse Verzögerung (Aufbau der Form) eintritt. Beim zweiten Mal, wenn die Form schon einmal geladen wurde geht es schneller.
    Dies hängt wahrscheinlich auch mit dem Laden der Control Libraries zusammen. Was mir generell nicht gefällt ist, dass die jetzige Anwendung ein MDI verwendet, obwohl immer nur ein Formular angezeigt wird. Aber das hat auch andere Gründe.

    Nun ist es meine Aufgabe, das "Hauptformular" neu zu definieren und die gesamte Fensterverwaltung zu handeln. Meine Idee wäre, die Fenster alle vorladen und die Instanzen in einer Liste zu speichern. Wenn nun ein Fenster aktiv werden soll,
    dann diese Instanz holen und das Fenster anzeigen (Keine Ahnung, ob das überhaupt geht) . Ein weiteres Problem was ich sehen ist, das Vorladen der Fenster. Weil jedes Fenster will beim Laden den Focus haben und auch angezeigt werden. Wie kann ich die Fenster im Hintergrund vorladen?
    Ich könnte es außerhalb des sichtbaren Bereiches machen, aber gibt es dazu vielleicht eine bessere Lösung? Hatte jemand das gleiche Problem? Vielleicht ist ein Vorladen überhaupt nicht notwendig und man lädt einfach alle Control Libraries?
    Noch ein Hinweis, wenn nun ein Formular geöffnet wurde und der Benutzer wechselt in ein anderes Formular und wieder zurück, dann soll genau das alte Formular mit den Daten wieder angzeigt werden. Also ein Dispose etc. ist nur beim Beenden der Anwendung sinnvoll.

    Wäre für Anregungen, Tipps und Hilfen dankbar.

    Thema verschoben ~VaporiZed

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()

    Ich finde MDI-Anwendungen meist minder sinnvoll.
    Kein Mensch benutzt das wirklich - also dass man da viele grosse und kleine Fensterchen im Fenster hin und herschiebt, und dann nicht findet, weil sie übereinanderliegen und den ganzen Quark.
    Jeder benutzt MDI ausschliesslich mit maximierten Child-Windows - also im Grunde als tabbed Anwendung.

    Daher besser ist eine Tabbed-Anwendung, und auf jedem Tab ein UserControl legen.
    Braucht man wirklich viele Tabs, so kann man die TabReiter auch verstecken, und eine andere Art der Navigation zwischen den Tabs basteln - entwa ein Menü, oder eine Side-Bar.

    Allerdings riesige Anwendungen sind immer ein Problem.
    Lädt man alles auf einmal hat man Wartezeiten beim Startup, und das Teil belegt enorm Speicher.
    Lädt man Tabs sukzessive entstehen (kurze) Wartezeiten beim Aufrufen einzelner Tabs.
    Vor allem erfordert sukzessives Laden (und Ent-laden) Coding-Aufwand - insbesondere wenn beim zurück-switchen der vorherige Zustand wieder herzustellen ist.

    Man muss auch immer genau analysieren, was es ist, was lange dauert.
    Das kann ein schlechtes Datenhandling sein, wenn dieselben Daten immer wieder neu geladen werden, obwohl sie längst vorhanden sind.
    Oder dieselben Daten werden mehrfach geladen.

    Aber häufiger noch drückt ein Datagridview-Bug die Performance
    Da kommts sehr oft zum Missverständnis, dass man denkt das Daten-Laden dauert - und dabei ists das angebundene DGV, was minutenlang überlegt, ob und wie es die Daten dann schliesslich doch noch anzeigt.

    Wie gesagt: Performance-Probleme muss man immer(!!!!) erst genau(!!) untersuchen, bevor man eine Lösung in Angriff nimmt.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    - MDI finde ich auch nicht optimal. Außerdem in der aktuellen Anwendung nicht sinnvoll.
    - Sidebar habe ich mir auch schon überlegt, aber da gibt es gewisse Vorgaben. Ist nicht so einfach zu ändern.
    - Also meiner Meinung sind es die vielen Controls im Formular. Ich habe einmal ein Formular mir ca. 70 Controls gebaut ohne irgendeine Datenverbindung etc. Da konnte man "quasi" zusehen wie das Fomrular geladen wurde.
    - Bezüglich Datenanbindung schaut es so aus, dass max. ein Datensatz einer Tabelle geladen wirds. Wenn ein Grid enthalten ist, dann sind es Anpsrechpartner und das hält sich auch in Grenzen.

    Aber vielleicht hat ja jemand noch eine Idee oder ein ähnliches Problem...

    GerhardW schrieb:

    Ich habe einmal ein Formular mir ca. 70 Controls gebaut
    Tja - muss man angucken.
    Von 70 Controls täte ich noch nicht erwarten, dass es laggt.
    Also verteilt über mehrere Tabs.
    Vielleicht hast du ja lauter Images und Wackelbildchen und Kram eingebastelt...
    In einer Ansicht 70 Controls würden mich aber nachdenklich machen, ob das ein gutes Layout ist. Ich hab immer ein paar DGVs, paar Textboxen, und höchstens noch paar Knöppe - das isses dann aber auch.
    Schau mal im Ausgabefenster wieviele Fehler dort zur Laufzeit aufgelistet werden. Da laufen auch die per try/catch gefangenen Fehler rein.

    Hatte es schon, dass in einer Schleife immer der gleiche Fehler geworfen wurde und so das Programm extrem ausgebremst hat.
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen

    GerhardW schrieb:

    obwohl immer nur ein Formular angezeigt wird.
    In diesem Moment kannst Du die MDI-Philosophie weglassen, es sei denn, dass das Child-Fenster im Rahmen des Main-Fensters gefangen sein soll.
    Wenn es dann möhlich sein soll oder nicht, dass das Child-Fenster und das Main-Fenster gleichzeitig bedient werden soll, dann .Show() bzw. .ShowDialog().
    Wenn .Show(), beantworte die Frage, ob das Child-Fenster hinter das Main-Fenster geklickt werden können soll oder nicht, dann .Show() bzw. .Show(Me).
    Wenn Du diese Punkte alle beantwortet hast, stell bitte Deine Antworten vor, dann sehen wir weiter.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Also vielleicht habe ich es falsch beschrieben oder erklärt und außerdem habe ich vergessen, dass teilweise von DevEpxress Controls verwendet werden. Dies sollte aber nicht wirklich das Problem sein, ich habe mit den Dev Tools gute Erfahrungen bis jetzt gemacht.

    Aktuelle Version (nicht von mir und ist über Jahre entstanden und gewachsen, wurde nie an neue Techniken angepasst):
    Ist eine MDI Anwendung, wo immer nur ein einziges Formular innerhalb des MDI Parent angezeigt wird und zwar quasi "Maximized". Quasi "Maximized" deshalb ,weil das Hautpformular eine bestimmte Größe hat und nicht verändert werden kann. Alle Formulare sind als MDIChild definiert und mit

    Quellcode

    1. Show()
    geöffnet. Wenige werden mit

    Quellcode

    1. ShowDialog
    geöffnet. Es gibt im MDI Parent einige Buttons (Navigation durch die Datensätze) etc. und eine ToolBar. Die ganze Fensterverwaltung wird über eine eigene Klasse gemacht. Es werden eigentlich die Features von MDI nicht verwendet!
    Anbei ein ScreenShot vom Auswahlmenü nach der Anmeldung. Ein MDIChild, über die Buttons wird auf ein anderen Formular gewechselt.

    .. und hier noch ein Formular mit Tabs und den vielen Controls. Die Anzahl der Felder im Formular muss momentan so sein, weil parallel noch mit SuperBase gearbeitet wird. Unsere neue App soll dann SuperBase ablösen.

    Dieses Formular ist z.B. momentan an nichts gebunden. Wenn zwischen den Tabs geschaltet wird, dann ist mit blosem Auge der Formularaufbau erkennbar. Bei den anderen Formularen, welche z.B. einen Datensatz anzeigen ist es auch so.

    Meine Frage bzw. Ansatz wäre folgender:
    Weg von MDI. Ein Hauptformular, welches mir alle anderen Formulare managed. Die Fenster müssen noch immer dem Hautpformular "untergeordnet" sein, weil ich ja über die Navigations Buttons etc. im aktiven Formular ja etwas auslösen möchte. Die Kommunikation zwischen "Unterformular" und "Hauptformular" wird im Hauptformular angewickelt. Es muss auch möglich sein, dass ich ein Formular von der ToolBar direkt ansprechen kann. Des Weiteren ist es mir wichtig, dass die Umschaltung zwischen den Formularen zückig geht. Derzeit sehen ich immer, wie das Formular aufgebaut wird d.h. es jetzt nicht so schlimm, aber ich kann es wie gesagt, mit dem blosen Auge erkennen. Vielleicht lässt sich das vermeiden. Bei der aktuellen Version ist es so, dass fast alle Formulare nach der Anmeldung geladen werden. Ich habe es soweit geteste und muss sagen, ja die Umschaltung funktioniert schneller gegenüber einer neuen Instanz und dann mit Show() anzeigen (siehe Anhang Auftragsverwaltung.png). Die Datenanbindung kann für die Verzögerung es meiner Meinung nach nicht sein. Hier werden meistens nur ein Datensatz geladen.

    Was möchte ich:
    Mir geht es grundsätzlich darum, gibt es eine Möglichkeit Formulare "quasi" vorzuladen und bei Bedarf anzuzeigen. Um Verzögerungen zu vermeiden sollte, soweit ich mich eingelesen habe, die Libraries von den Controls einmal geladen werden. Bei einem Fensteraufbau, werden diese ja entsprechend den Controls in der Form nachgeladen, sofern nicht schon geladen. Deshalb ist beim Aufruf eines Formularen der erste Aufruf langsamer als der zweite Aufruf. Das Problem mit dem Vorladen ist allerdings, dass es dazu nichts gibt. Laden geht eben nur über

    Quellcode

    1. Show()
    und da möchte die Form den Focus haben und diese wird auch angezeigt. Wenn ich es in einer Schleife mache, dann kann ich zusehen, wie die einzelnen Formen geladen werden. Als letzte dann das AuswahlFenster. Aber das ich unfug.
    Die Formulare selbst bleiben während der Anwendung offen und es wird immer das ausgewählte Formular an oberster Stelle gereiht (so mit

    Quellcode

    1. BringToFront
    etc.). Deshalb auch meine Idee mit der FormListe, wo die Instanzen und der FormTyp abgespeichert werden.

    Vielleicht hat jemand eine Idee?

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „GerhardW“ ()

    @GerhardW Zunächst nutze bitte die Datai-Anhangs-Funktionalität des Forums: Erweiterte Antwort => Dateianhänge => Hochladen.
    Ich sehe schon, das wird so ein komplexes Auftrags-Management, das ist nicht so meine Richtung, ich bin eher in Hardware-Ansteuerung, Datenerfassung und -Auswertung.
    Möglicherweise ist das TabControl ohne Reiter vom @ErfinderDesRades da was für Dich.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Jo, wie gesagt: Wenn das MDI am MDI nicht benutzt wird, dann soll man MDI lassen.
    Statt UnterForms kann man UserControls verwenden - die kann man ebensogut im FormDesigner designen.
    Und dann finde heraus, warum es laggt.
    Bastel eine tabbed-Anwendung und mach deine 70 Controls drauf, und guck, obs laggt.
    Wenns nicht laggt, hats wohl was mit Daten zu tun.
    Wenns laggt, liegts an Controls.
    Untersuche, an welchen Controls es liegt.

    Bau nicht irgendwelche neuartigen Tab-Verwaltungen, ehe nicht geklärt ist, warum es laggt.

    (Jo - und die Bilder guck ich mir so nicht an.)
    @GerhardW Wenn die Bilder nun "richtig" drin sind, kannst Du die "falschen Links" auch löschen.
    Du kannst die Bilder auch genau da einblenden, wo Du sie hinhaben willst:
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!