Laden...

Aufbau einer Winformanwendung (panels, tabs, etc)

Erstellt von NilsA vor 15 Jahren Letzter Beitrag vor 15 Jahren 1.804 Views
N
NilsA Themenstarter:in
89 Beiträge seit 2006
vor 15 Jahren
Aufbau einer Winformanwendung (panels, tabs, etc)

Hallo,
WinForms sind nun wirklich nicht mein Gebiet, aber ich versuche mich doch immer wieder daran.
Leider scheitern meine kleinen Tools immer an der Umsetzung des Forms.

Meine bisherigen Versuche mit z.B. Tabs sahen so aus:

TabPage 1. eine "Loginseite" welche bei erstmaligem Start des Programms das Masterpasswort haben möchte.

TabPage 2. hier erscheinen ein paar Dropdown Listen, Buttons und Eingabefelder.

TabPage 3. hier soll der User die Möglichkeit haben das Masterpasswort zu ändern.

Mein Plan war beim Start alle TabPages zu Deaktivieren, so dass der Login erzwungen wird. Das geht ja leider schon gar nicht. 😦

Dann hatte ich auch mal eine Lösung mit Panels, die Alle übereinander lagen und die verschiedenen "Formulare" enthalten haben. Das ist noch schlechter, weil ich bei jeder Änderung ein riesen hin- und hergeschiebe habe.

Mache ich hier im aufbau grundsätzlich etwas falsch? Ich wollte die 3 TabPages nicht auf 3 Formulare verteilen, weil das optisch nicht so schön ist. 1 Formular ist offen, 2. geht auf, oft leicht versetzt, bzw. man "merkt" einfach das man auf einem neuen Formular ist.
Wie macht ihr das, bzw. wie macht man sowas richtig?

Gruß
Nils

Je mehr ich weiß, desto mehr erkenne ich, dass ich nichts weiß.
(Albert Einstein) ...und ich kanns bestätigen 😉

2.760 Beiträge seit 2006
vor 15 Jahren

Wie macht ihr das, bzw. wie macht man sowas richtig?

z.B. so: [FAQ] Mit Forms eine Art Frameset einer Website nachbauen?

N
NilsA Themenstarter:in
89 Beiträge seit 2006
vor 15 Jahren

Hallo jaensen,
vielen dank erstmal für deine Antwort!
Leider hänge ich schon gleich wieder fest. Ich habe jetzt die Umsetzung von ErfinderDesRades genommen, da sie einfacher aussah. ABER:

Mein Problem bleibt bestehen. Ich habe jetzt
Tab1 (Masterpasswort erstellen)
Tab2 (Login)
Tab3 (eigentlicher inhalt)

Ich prüfe nun in meinem Tool ob es sich um den ersten login handelt, wenn ja dann Zeige nur Tab1, wenn nein zeige Tab2

Das geht leider schon nicht.
Ich kann zwar jeweils im "Menü" Tab1 oder Tab2 anzeigen, aber im eigentlichen Content-Bereich wird immer Tab1 angezeigt.

Lasse ich im Menü alle Tabs anzeigen und wähle sie manuell an, passt wieder alles. Aber ich möchte ja nicht, das man nach dem Login nochmal auf den "Masterpasswort erstellen" oder "Login" Tab kann.

Anbei ein paar Code-Auszüge (da ich das ganze leicht angepasst habe)

Bei Programmstart:


public PasswordReminder()
        {
            InitializeComponent();

            //diese Einstellungen verstecken die Reiter erst zur Laufzeit
            //zur Design-Zeit sind die Reiter ja sehr nützlich 
            tcMenu.SizeMode = TabSizeMode.Fixed;
            tcMenu.ItemSize = new Size(0, 1);
            tcMenu.Appearance = TabAppearance.Buttons;

            this.lbMenu.SelectedIndexChanged += new EventHandler(lbMenu_SelectedIndexChanged);
            // beim ersten Login nur Masterpasswort-Tab anzeigen
            if (bll.CheckFirstLogin())
            {
                ShowMenuTabs(tpFirstLogin);
            }
            // ansonsten alle Tabs anzeigen
            else
            {
                //ToDo
            }
            this.lbMenu.DisplayMember = "Text";
            lbMenu.SelectedIndex = 0;
        }

Zeige Tabs in Menü + Tab auswählen


private void ShowMenuTabs(TabPage Page)
        {
            lbMenu.Items.Clear();
            lbMenu.Items.Add(Page);
            tcMenu.SelectTab(Page.Name);
        }

Gruß
Nils

Je mehr ich weiß, desto mehr erkenne ich, dass ich nichts weiß.
(Albert Einstein) ...und ich kanns bestätigen 😉

456 Beiträge seit 2007
vor 15 Jahren

Hallo Nils,

hier trifft man sich also wieder, nun, die Welt ist ja verdammt klein 😁 ...

Ich würde das Tab Control nur dann verwenden, wenn der Benutzer Einstellungen vornehmen kann, also ganz einfach Werte setzen und diese müssen auch im Context zusammengehören - aber ich würde das Teil nie verwenden um irgendswelche (aufwendige) Businesslogik reinzubauen. Also aktivieren, wenn Tab 1 und dann deaktivieren und nicht anzeigen wenn ... usw.

Probiere es doch einfach mit User Controls, Benutzer jaensen hat ja schon den Link gepostet. Ich schlage Dir auch mal meine Lösung vor, klickst Du >> hier <<

Ferner sind für ein Login immer sog. Splash-Screens interessant. Gibt es hier im Forum auch zig Einträge und auch vorgefertigte Klassen.

Gruß von Hallstadt rüber nach Bamberg

5.299 Beiträge seit 2008
vor 15 Jahren

Also statt groß Logik dranzumachen (die habichnich kapiert), habichmal eine Checkbox auf Tab1 gemacht, und Tab2 ist nur anwählbar, wenn die gecheckt ist:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace FrameSetLike {
   public partial class frmFrameSetLike : Form {

      public frmFrameSetLike() {
         InitializeComponent();

         //diese 3 Einstellungen verstecken die Reiter zur **Laufzeit**
         //zur Design-Zeit holt man mit ihnen ja sehr bequem die Pages
         tabControl1.SuspendLayout();
         tabControl1.SizeMode = TabSizeMode.Fixed;
         tabControl1.ItemSize = new Size(0, 1);
         tabControl1.Appearance = TabAppearance.Buttons;
         tabControl1.ResumeLayout();

         this.listBox1.SelectedIndexChanged += new EventHandler(listBox1_SelectedIndexChanged); 
         listBox1.Items.Add( tabControl1.TabPages[0]);
         this.listBox1.DisplayMember = "Text";
         listBox1.SelectedIndex = 0;
      }

      void listBox1_SelectedIndexChanged(object sender, EventArgs e) {
         this.tabControl1.SelectedIndex = listBox1.SelectedIndex;
         //TabControl ist bisserl doof - es nimmt den Focus, auch wenn nur per Code selektiert wurde
         listBox1.Focus();             //Focus zurück zur Listbox
      }

      private void checkBox1_CheckedChanged(object sender, EventArgs e) {
         if (checkBox1.Checked) listBox1.Items.Insert(1, tabControl1.TabPages[1]);
         else listBox1.Items.RemoveAt(1);
      }
   }
}

Der frühe Apfel fängt den Wurm.

5.299 Beiträge seit 2008
vor 15 Jahren

Jetzt habich über die Logik nachgedacht, und komme zu dem Schluß, daß kein Menu erwünscht ist:

Der frühe Apfel fängt den Wurm.

N
NilsA Themenstarter:in
89 Beiträge seit 2006
vor 15 Jahren

Hallo und danke für die Antworten,

Eigentlich ist schon ein Menü erwünscht, aber erst nach dem Login.
Dort soll es dann den "Content", also die eigentliche Aufgabe meines Tools geben und zusätzlich noch ein Tab mit "Masterpasswort ändern". Das wird es zwar wahrscheinlich nicht sofort geben, aber ich werde diese Funktion auf jeden Fall integrieren.

Das bedeutet ich brauche später schon ein Menü. Ich konnte mir deine Lösung noch nicht ansehen, werde es aber heute Abend mal machen. Vermutlich komme ich damit sogar schon weiter.

@mosspower
Ich hab gehört du hast meinen Saustall schon aufgeräumt und alles neu gemacht. Das war wohl auch die beste Lösung. Irgendwie hat meine Software durch die ständige Erweiterung schon 2 Wasserköpfe gehabt 😉

Gruß
Nils

Je mehr ich weiß, desto mehr erkenne ich, dass ich nichts weiß.
(Albert Einstein) ...und ich kanns bestätigen 😉

N
NilsA Themenstarter:in
89 Beiträge seit 2006
vor 15 Jahren

Hallo nochmal!

So, ich habe das Problem vorerst gelöst, jedoch - wie ich finde- unschön.
Anbei der Code mit Erklärung des Problems + "Lösung".

Die Problemlösung geschieht jetzt im event lbMenu_SelectedIndexChanged


public PasswordReminder()
        {
            InitializeComponent();

            //diese Einstellungen verstecken die Reiter erst zur Laufzeit
            //zur Design-Zeit sind die Reiter ja sehr nützlich 
            tcMenu.SizeMode = TabSizeMode.Fixed;
            tcMenu.ItemSize = new Size(0, 1);
            tcMenu.Appearance = TabAppearance.Buttons;

            this.lbMenu.SelectedIndexChanged += new EventHandler(lbMenu_SelectedIndexChanged);
            // beim ersten Login nur Masterpasswort-Tab anzeigen
            if (bll.CheckFirstLogin())
            {
                ShowMenuTabs(tpFirstLogin);
                tcMenu.SelectedIndex = 0;
            }
            // ansonsten alle Tabs anzeigen
            else
            {
                ShowMenuTabs(tpLogin);
                tcMenu.SelectedIndex = 1;
                //ToDo: ALT... löschen!
                //foreach (TabPage tp in this.tpLogin.TabPages)
                //{
                //    lbMenu.Items.Add(tp);
                //}
            }
            this.lbMenu.DisplayMember = "Text";
            
        }


// sorgt dafür das im Menü nur 1 Tab angezeigt wird
        private void ShowMenuTabs(TabPage Page)
        {
            lbMenu.Items.Clear();
            lbMenu.Items.Add(Page);
        }


//für mehrere Tabs
        private void ShowMenuTabs(List<TabPage> Pages)
        {
            for (int i = 0; i < Pages.Count; i++)
            {
                lbMenu.Items.Clear();
                lbMenu.Items.Add(Pages[i]);
            }
        }
[CSHARP]

[CSHARP]
private void lbMenu_SelectedIndexChanged(object sender, EventArgs e)
        {
            //Problem: Durch ausblenden von "Masterpasswort" hat "Login" im Menü eine
            //          andere ID als der zugehörige TAB
            //Lösung: Alle TABs auslesen und Name + ID in Dict schreiben.
            //          anschließend über Name vom Menü (== TabName) die ID holen

            Dictionary<string, int> TabIndex = new Dictionary<string, int>();
            int counter = 0;
            
            foreach(TabPage Page in tcMenu.TabPages)
            {
                TabIndex.Add(Page.Text, counter);
                counter++;
            }
            this.tcMenu.SelectedIndex = TabIndex[lbMenu.Text];
            //TabControl ist bisserl doof - es nimmt den Focus, auch wenn nur per Code selektiert wurde
            lbMenu.Focus();
        }

Was sagt ihr zu dieser Lösung?

Gruß
Nils

Je mehr ich weiß, desto mehr erkenne ich, dass ich nichts weiß.
(Albert Einstein) ...und ich kanns bestätigen 😉