none
Mit ausführen des Codes warten bis Benutzer mit Eingabe von Daten fertig ist... RRS feed

  • Frage

  • Hi

    Habe ein kleines Problem und wär dankbar wenn mir da jemand helfen könnte:

    Es soll eine 2.WindowsForm aufgehen, inwelche man Daten eingeben kann...diese Daten sollen dann in die ursprüngliche Form zurückgeliefert werden...hier das Beispiel:

    public void button1_Click(object sender, EventArgs e)
            {
                frmEinstellungen frmEinstellungen = new frmEinstellungen(); //frmEinstellungen: ist die 2.WinForm
                frmEinstellungen.Show();
    
    //an dieser Stelle müsste das Programm jetzt mit dem Ausführen des Codes solange warten, bis der Benutzer die 
    //2.WinForm wieder geschlossen hat...da die jetzt vom Benutzer eingebenen Daten nicht aufgenommen werden können...(da sie ja nicht gleich nach dem Öffnen der Form drinnenstehen)
    
    //hier werden die Daten in ein Objekt der Class Einstellungen übergeben(mit der unten aufgeführten Methode):
    
                Einstellungen E1 = new Einstellungen();
                E1 = Einstellungen.getEinstellungen();
            }
    
    
    
    //folgende Methode befindet sich nun in der 2.WinForm (wobei Einstellungen eine Class ist!):
    
    internal Einstellungen getEinstellungen()
            {
                Einstellungen E1 = new Einstellungen();
                E1.setEinstellungen(//an dieser Stelle befinden sich mehrere Variablen...vom Benutzer eingeben(hauptsächlich doubles, int, strings));
                return E1;
    
    //setEinstellungen: ist eine Methode der Class Einstellungen
            }

    Was ich jetzt möchte ist das die 1.Form die Daten die in die 2.Form eingegeben wurden bekommt...

    Könnte mir da vllt. jemand helfen?

    Lg

    GeilsterTyp

    Sonntag, 26. Juni 2016 15:33

Antworten

  • Die Schleife dürfte in deiner Anwendung alles weitgehend blockieren.

    Was du aber machen möchtest, nennt man "einen modalen Dialog anzeigen":

    frmEinstellungen.ShowDialog()

    Das so geöffnete Form sperrt automatisch das Parentform, d.h. solange frmEinstellungen geöffnet ist sind die anderen Forms deiner Anwendung praktisch gesperrt. Diese Methode ist in deiner Parentform und ruft den modalen Dialog auf: (im Click-Event eines Buttons...)

    // behandelt ein Button-Click-Ereignis im "Hauptformular"
    private void EinstellungenBearbeiten_Click(object sender, EventArgs e) {

    // derartige Dialoge sollte man in einem "using-Block" abhandeln, dann wird das
    // Dialog-Form im Anschluss automatisch sauber entsorgt.
    // 1. using ( frmEinstellungen editor = new frmEinstellungen() ) {

    // eine Referenz auf das Einstellungs-Daten-Object an das Dialog-Form weiterreichen...
    // 2. editor.einstellungen = einstellungen;

    // den Dialog modal aufrufen und das Ergebnis später auswerten
    // 3. if ( editor.ShowDialog(this) == DialogResult.OK ) {

    // falls OK, Werte anzeigen. Hier musst du deine eigene Verarbeitung starten... MessageBox.Show("Einstellung 1 = " + einstellungen.Einstellung1.ToString() + Environment.NewLine + "Einstellung 2 = " + einstellungen.Einstellung2); } } }

    Das frmEinstellungen wird in einem "using-Block" (1.) instanziiert, somit muss es nicht mehr explizit freigegeben werden (Dispose).

    frmEinstellungen sollte nichts weiter machen, als die erhaltenen Daten (2.) zu editieren und bei Klick auf einen OK-Button zurückzugeben und über den Cancel-Button des Dialog-Forms werden die eventuell gemachten Änderungen verworfen (nicht übernommen)...

    Jedes Form hat eine Eigenschaft "DialogResult", die hier genutzt wird.

    Egal, welchen Exit-Button-Click (OK, Cancel) du im modalen Fenster behandelst, du solltest das Fenster nicht mit Close() schließen sondern besser mit Hide(), damit es später noch sicher ausgewertet werden kann.

    Damit wird praktisch die Kontrolle an das ParentForm zurück gegeben (3.), welche das "DialogResult"-Ergebnis auswerten kann.

    Probiere einfach mal aus, was passiert wenn du den frmEinstellungen mit .ShowDialog() öffnest.

    Und mach die Schleife weg :-)

    Gruß


    Sonntag, 26. Juni 2016 18:52
  • ...aber ein größeres Problem gibts noch: In meiner Einstellungsform (also die 2.Form) gibt es nicht nur einen OK-Button, sondern auch einen Abbrechen-Button...Wenn ich auf diesen klicke funktionierts leider nicht so wie es sollte... ... wenn ich jetzt auf Abbrechen drück, legt es ebenfalls eine neue Zeile an
    public void button1_Click(object sender, EventArgs e)
            {
                frmEinstellungen frmEinstellungen = new frmEinstellungen();
                frmEinstellungen.ShowDialog();
    
    //hier müsste der Code jetzt stoppen wenn in frmEinstellungen auf "Abbrechen" gedrückt wurde....
    
    
                Einstellungen E1 = new Einstellungen();
                E1 = Einstellungen.getEinstellungen();
            }

    Und noch eine kleine Frage: Was ist ein using block?...und warum sollte ich mein Vorhaben in solch einem machen?

    Der Methodenaufruf in:

    frmEinstellungen.ShowDialog();

    liefert dir auch ein Ergebnis zurück, welches du auswerten kannst:

    DialogResult dr = frmEinstellungen.ShowDialog();
    if (dr == DialogResult.OK) {
    	// Daten verwenden
    } else {
    	// Daten nicht verwenden
    }

    Wenn du das verwendest, kannst du ja klar unterscheiden, ob OK oder Cancel gedrückt wurde (s. auch mein vorheriges Beispiel).

    Ich würde so vorgehen:

    1. Klasse erstellen, die alle Einstellungen als Propertys implementiert
    2. Dem frmEinstellungen eine öffentliche Eigenschaft mitgeben, in der du eine Referenz auf eine Instanz deiner Einstellungen-Klasse ablegst
    3. Die Instanz von frmEinstellungen nur zum Editieren der Einstellungsdaten verwenden, als modaler Dialog aufrufen und
    4. das Ergebnis (DialogResult) verwenden, um festzustellen, ob OK oder Cancel gedrückt wurde.

    Noch zur Frage:
    Wie kann man so einen Abbrechen-Button programmieren, das praktisch die Einstellungsform einfach geschlossen wird...

    // der OK-Button, falls alles in Ordnung ist
    private void btnOK_Click(object sender, EventArgs e) {
      DialogResult = DialogResult.OK;
      // ...
      Hide();
    }
    
    // der Cancel-Button, falls die Einträge verworfen werden
    private void btnCancel_Click(object sender, EventArgs e) {
      // Dialogresult festlegen auf "Cancel"
      DialogResult = DialogResult.Cancel;
      Hide();
    }

    using (...) { } stellt sicher, dass das Dialog-Form entsorgt werden kann.

    using kannst du in aller Regel für alle Klassen verwenden, die IDisposable implementieren...

    Gruß


    Montag, 27. Juni 2016 19:31

Alle Antworten

  • Hi,

    in deinem "frmEinstellungen" deklarierst du eine öffentliche Eigenschaft, der du dann eine Instanz deiner Einstellungen-Klasse zuweist. Im "Shown" Ereignis weist du dann die Eigenschaften dieser Instanz den passenden Steuerelementen zu.

    Die frmEinstellungen hat dann normal zwei Buttons, "OK" und "Cancel" oder so ähnlich.

    Im Hauptform rufst du das frmEinstellungen mit "frmEinstellungen.ShowDialog()" statt ".Show()" auf, damit es ein modaler Dialog wird.

    Also, im Hauptform in etwa so:

    Einstellungen einst = new Einstellungen();
    
    private void button1_Click(object sender, EventArgs e) {
    	using ( frmEinstellungen ed = new frmEinstellungen () ) {
    		ed.einstellungen = einst;
    		if ( ed.ShowDialog(this) == DialogResult.OK ) {
    			MessageBox.Show("Einstellung 1 = " + einst.Einstellung1.ToString() + 
    				Environment.NewLine + "Einstellung 2 = " + einst.Einstellung2);
    		}
    	}
    }

    Im Einstellungen-Form so:

    public frmEinstellungen () { InitializeComponent(); this.Shown += frmEinstellungen_Shown; }

    // Daten zuzweisen private void frmEinstellungen_Shown(object sender, EventArgs e) { if (einstellungen != null) { numericUpDown1.Value = einstellungen.Einstellung1; textBox1.Text = einstellungen.Einstellung2; } }

    // Eigenschaft wird vom FormMain beschickt... public Einstellungen einstellungen { get; set; }

    // der OK-Button... private void button1_Click(object sender, EventArgs e) { DialogResult = DialogResult.OK; if ( einstellungen != null ) { einstellungen.Einstellung1 = numericUpDown1.Value; einstellungen.Einstellung2 = textBox1.Text; } Hide(); }

    // der Cancel-Button... private void button2_Click(object sender, EventArgs e) { DialogResult = DialogResult.Cancel; Hide(); }

    Im Beispiel hat das frmEinstellungen bei mir ein NumericUpDown und ein TextBox-Control, die Klasse Einstellungen sieht so aus:

    public class Einstellungen {
    	public decimal Einstellung1 { get; set; }
    	public string Einstellung2 { get; set; }
    }

    So könnte es gehen, sonst frag noch mal nach...

    Gruß




    • Bearbeitet K. Pater Sonntag, 26. Juni 2016 16:17
    Sonntag, 26. Juni 2016 16:08
  • Ich hab selber schon mal was ausprobiert:

    //...
    while(frmEinstellungen.Visible == true)
    {
    //hier einfach nichts machen...bis der Benutzer eben fertig mit der Eingabe der Daten ist...
    }
    //...

    Das Problem hierbei ist einfach das die Einstellungsform dann nicht ordnungsgemäß geöffnet wird, sprich es werden keine Textboxen oder Labels angezeigt...warum geht das so nicht?

    Das was du da grad erklärt hast ist echt viel und um ehrlich zu sein versteh ich relativ wenig davon...könntest du es vllt. nochmals erklären mit vielen Anmerkungen, dass ich weiß was wo passsiert?...Wär echt nett...

    Danke schon mal

    LG

    Sonntag, 26. Juni 2016 16:22
  • Die Schleife dürfte in deiner Anwendung alles weitgehend blockieren.

    Was du aber machen möchtest, nennt man "einen modalen Dialog anzeigen":

    frmEinstellungen.ShowDialog()

    Das so geöffnete Form sperrt automatisch das Parentform, d.h. solange frmEinstellungen geöffnet ist sind die anderen Forms deiner Anwendung praktisch gesperrt. Diese Methode ist in deiner Parentform und ruft den modalen Dialog auf: (im Click-Event eines Buttons...)

    // behandelt ein Button-Click-Ereignis im "Hauptformular"
    private void EinstellungenBearbeiten_Click(object sender, EventArgs e) {

    // derartige Dialoge sollte man in einem "using-Block" abhandeln, dann wird das
    // Dialog-Form im Anschluss automatisch sauber entsorgt.
    // 1. using ( frmEinstellungen editor = new frmEinstellungen() ) {

    // eine Referenz auf das Einstellungs-Daten-Object an das Dialog-Form weiterreichen...
    // 2. editor.einstellungen = einstellungen;

    // den Dialog modal aufrufen und das Ergebnis später auswerten
    // 3. if ( editor.ShowDialog(this) == DialogResult.OK ) {

    // falls OK, Werte anzeigen. Hier musst du deine eigene Verarbeitung starten... MessageBox.Show("Einstellung 1 = " + einstellungen.Einstellung1.ToString() + Environment.NewLine + "Einstellung 2 = " + einstellungen.Einstellung2); } } }

    Das frmEinstellungen wird in einem "using-Block" (1.) instanziiert, somit muss es nicht mehr explizit freigegeben werden (Dispose).

    frmEinstellungen sollte nichts weiter machen, als die erhaltenen Daten (2.) zu editieren und bei Klick auf einen OK-Button zurückzugeben und über den Cancel-Button des Dialog-Forms werden die eventuell gemachten Änderungen verworfen (nicht übernommen)...

    Jedes Form hat eine Eigenschaft "DialogResult", die hier genutzt wird.

    Egal, welchen Exit-Button-Click (OK, Cancel) du im modalen Fenster behandelst, du solltest das Fenster nicht mit Close() schließen sondern besser mit Hide(), damit es später noch sicher ausgewertet werden kann.

    Damit wird praktisch die Kontrolle an das ParentForm zurück gegeben (3.), welche das "DialogResult"-Ergebnis auswerten kann.

    Probiere einfach mal aus, was passiert wenn du den frmEinstellungen mit .ShowDialog() öffnest.

    Und mach die Schleife weg :-)

    Gruß


    Sonntag, 26. Juni 2016 18:52
  • Danke erstmal für die ausführlich erklärte Antwort!!

    Ich habs jetzt einfach mal ausprobiert und es hat tatsächlich schon gut funktioniert...aber ein größeres Problem gibts noch: In meiner Einstellungsform (also die 2.Form) gibt es nicht nur einen OK-Button, sondern auch einen Abbrechen-Button...Wenn ich auf diesen klicke funktionierts leider nicht so wie es sollte...

    Alle in der Einstellungsform eingegebenen Infos werden nämlich sofort nach dem Drücken des OK-Buttons in eine Tabelle eingefügt...und da wird jedes mal wenn man Daten in die Einstellungsform eingibt und auf Ok drückt eine neue Zeile angelegt, in die die Daten geschrieben werden...das passt auch so...

    Allerdings wenn ich jetzt auf Abbrechen drück, legt es ebenfalls eine neue Zeile an, in die es einfach überall "0" als eingegebenen Wert reinschreibt...das ist natürlich NICHT erwünscht!

    Wie kann man so einen Abbrechen-Button programmieren, das praktisch die Einstellungsform einfach geschlossen wird, und keine Daten aufgenommen werden...

    public void button1_Click(object sender, EventArgs e)
            {
                frmEinstellungen frmEinstellungen = new frmEinstellungen();
                frmEinstellungen.ShowDialog();
    
    //hier müsste der Code jetzt stoppen wenn in frmEinstellungen auf "Abbrechen" gedrückt wurde....
    
    
                Einstellungen E1 = new Einstellungen();
                E1 = Einstellungen.getEinstellungen();
            }
    

    Und noch eine kleine Frage: Was ist ein using block?...und warum sollte ich mein Vorhaben in solch einem machen?

    Lg

    Montag, 27. Juni 2016 15:48
  • ...aber ein größeres Problem gibts noch: In meiner Einstellungsform (also die 2.Form) gibt es nicht nur einen OK-Button, sondern auch einen Abbrechen-Button...Wenn ich auf diesen klicke funktionierts leider nicht so wie es sollte... ... wenn ich jetzt auf Abbrechen drück, legt es ebenfalls eine neue Zeile an
    public void button1_Click(object sender, EventArgs e)
            {
                frmEinstellungen frmEinstellungen = new frmEinstellungen();
                frmEinstellungen.ShowDialog();
    
    //hier müsste der Code jetzt stoppen wenn in frmEinstellungen auf "Abbrechen" gedrückt wurde....
    
    
                Einstellungen E1 = new Einstellungen();
                E1 = Einstellungen.getEinstellungen();
            }

    Und noch eine kleine Frage: Was ist ein using block?...und warum sollte ich mein Vorhaben in solch einem machen?

    Der Methodenaufruf in:

    frmEinstellungen.ShowDialog();

    liefert dir auch ein Ergebnis zurück, welches du auswerten kannst:

    DialogResult dr = frmEinstellungen.ShowDialog();
    if (dr == DialogResult.OK) {
    	// Daten verwenden
    } else {
    	// Daten nicht verwenden
    }

    Wenn du das verwendest, kannst du ja klar unterscheiden, ob OK oder Cancel gedrückt wurde (s. auch mein vorheriges Beispiel).

    Ich würde so vorgehen:

    1. Klasse erstellen, die alle Einstellungen als Propertys implementiert
    2. Dem frmEinstellungen eine öffentliche Eigenschaft mitgeben, in der du eine Referenz auf eine Instanz deiner Einstellungen-Klasse ablegst
    3. Die Instanz von frmEinstellungen nur zum Editieren der Einstellungsdaten verwenden, als modaler Dialog aufrufen und
    4. das Ergebnis (DialogResult) verwenden, um festzustellen, ob OK oder Cancel gedrückt wurde.

    Noch zur Frage:
    Wie kann man so einen Abbrechen-Button programmieren, das praktisch die Einstellungsform einfach geschlossen wird...

    // der OK-Button, falls alles in Ordnung ist
    private void btnOK_Click(object sender, EventArgs e) {
      DialogResult = DialogResult.OK;
      // ...
      Hide();
    }
    
    // der Cancel-Button, falls die Einträge verworfen werden
    private void btnCancel_Click(object sender, EventArgs e) {
      // Dialogresult festlegen auf "Cancel"
      DialogResult = DialogResult.Cancel;
      Hide();
    }

    using (...) { } stellt sicher, dass das Dialog-Form entsorgt werden kann.

    using kannst du in aller Regel für alle Klassen verwenden, die IDisposable implementieren...

    Gruß


    Montag, 27. Juni 2016 19:31
  • Dankesehr...ich meld mich falls ich noch fragen haben sollte...Vielen vielen Dank für die ausführliche Erklärung...

    Lg

    Geilster Typ

    Dienstag, 28. Juni 2016 14:04