C# Button muss zwei mal geklickt werden

Seiyaru2208

Captain
Registriert
Apr. 2008
Beiträge
3.111
Hallo Jungs,

ich habe folgendes Problem, ich habe ein Dialog Fenster mit zwei Checkboxen.

Ziel ist es das der Nutzer eine der beiden Checkboxen ausgewählt haben muss bevor er fortfahren kann. Grundlegend habe ich dies mit einer while-Schleife gelöst. Das einzige kleine Problem ist, das ich zweimal den bnt.Weiter anklicken muss bevor es weiter geht.

Könnt ihr mir ein tipp geben warum es nicht beim ersten Click weitergeht?

Code:
namespace AZAV_TEST
{
    public partial class Abfrage_6W_6M : Form
    {
        public Abfrage_6W_6M()
        {
            InitializeComponent();
        }

        private bool sechsWochen = false;

        public bool SechsWochen
        {
            get { return sechsWochen; }
            
        }

        private bool sechsMonate = false;

        public bool SechsMonate
        {
            get { return sechsMonate; }
          
        }



        private void bntWeiter_Click(object sender, EventArgs e)
        {

           
            while (sechsWochen == false || sechsMonate == false)
            {
                if (cbx6Wochen.Checked == true || cbx6Monate.Checked == true)
                {
                    
                    sechsWochen = cbx6Wochen.Checked;
                    sechsMonate = cbx6Monate.Checked;
                    bntWeiter.DialogResult = DialogResult.OK;
                    break;

                   
                } 
                else
                {
                    MessageBox.Show("Bitte etwas ankreuzen");
                    return;
                }
            }
          }
    }
}

PS: Sollte eine Angabe zum Problem lösen fehlen , einfach sagen Ich bin noch Anfänger.
 
warum setzt du den weiter button nicht auf disabled und enabled s ihn wenn eine der checkboxen checked ist ? die while schleife macht so auch überhaupt gar keinen sinn, du solltest vll nochmal ganz genau überlegen was du erreichen möchtest
 
Warum nutzt du dafür eine Schleife??? Da wird doch gar nix wiederholt, eine If würde vollkommen ausreichen
 
Ich habe eine schleife gewählt weil ein If nicht funktioniert hat. der Button übergibt ja das DialogResult "OK" im Hauptprogramm danach das entsprechende PDF gewählt und mit Daten gefüllt.

Bei If kam die MessengeBox 1x und es ging weiter. Ich versuche es aber mal mit If auch wenn ich jetzt nicht das Problem sehe das in einer While schleife dazustellen, könnt ihr mich da aufklären?
 
Das is ein klassisches Beispiel von nur weil etwas funktioniert, muss es so nicht richtig sein. Eine Schleife ist dafür da etwas zu wiederholen, du willst aber einfach nur eine Abfrage machen. Es geht hier einfach um Stil und Wartbarkeit, wenn du in ein paar Monaten weiter bist und nochmal drauf guckst wirst du dich ne Weile lang fragen was die Schleife da soll, so wird es auch jedem gehen der deinen Code warten will.

Und um dir zu erklären warum deine eigentliche Abfrage nicht geklappt hat, wäre es gut den Code mal zu sehen. Denn eigentlich sollte das was du da machst genau so auch mit dem If klappen.
 
Ah okay verstehe. ich habe jetzt auch verstanden warum es beim ersten Versuch mit If nicht funktioniert hat. Ich hatte in den Button-eiegenschaften den DialogResult Default auf OK. Bei der While-Schleife habe ich dies wieder auf None gesetzt und in der Schleife gesagt wenn das passiert setze den Dialog.Result auf "OK"

Danke für die Erklärung, ihr habt recht mit IF geht es jetzt ich habe es so gelöst


Code:
 if (cbx6Wochen.Checked == true || cbx6Monate.Checked == true)
                {

                    sechsWochen = cbx6Wochen.Checked;
                    sechsMonate = cbx6Monate.Checked;
                    bntWeiter.DialogResult = DialogResult.OK;

                }
                else
                {
                    MessageBox.Show("Bitte etwas ankreuzen");

                }

Im Grund das gleiche nur ohne die Schleife. Das ich den button dennoch zwei mal anklicken muss besteht immer noch
 
Zuletzt bearbeitet:
Schonmal im Debugger geschaut ... 1. geht er wirklich 2mal in die Methode? 2. Wenn ja, was unterscheidet den ersten vom zweiten Aufruf?
 
Code:
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    public bool SixWeeks { get; private set; }
    public bool SixMonths { get; private set; }

    private void submitButton_Click(object sender, EventArgs e)
    {
        //DialogResult der Form (anstatt Button wie bei dir) nutzen
        DialogResult = DialogResult.OK;
        Close();
    }

    private void cancelButton_Click(object sender, EventArgs e)
    {
        DialogResult = DialogResult.Cancel;
        Close();
    }

    //CheckedChanged beider Checkboxen hierauf setzen
    private void checkBox_CheckedChanged(object sender, EventArgs e)
    {
        SixWeeks = weeksCheckBox.Checked;
        SixMonths = monthsCheckBox.Checked;

        submitButton.Enabled = SixWeeks || SixMonths;
    }
}

Du solltest Schleifen mit der Aufgabe auf etwas zu warten vermeiden wann immer möglich, und in diesem Fall ist es eindeutig nicht nötig.

Außerdem musst du hier noch im Designer "Enabled" vom Button auf False setzen.
 
Zuletzt bearbeitet:
Daß Du den Button zweimal drücken must hat folgenden Grund:
Wenn Du den Button da serste mal drückst, hat er keinen DialogResult eingestellt, liefert somit diesen zurück und bleibt dann in der Schleife solange hängen, bis eine der Checkboxen aktiviert wird. Jetzt wird bei deinem Button eingestellt, dass er beim Betätigen den DialogResult OK zurückliefern soll - er war ja aber bereits betätigt, also ändert das erst mal gar nichts. Erst wenn Du ihn das nächste Mal klickst kommt diese Einstellung zum Tragen und der Button liefert den DialogResult OK zurück.
Zum Einsatz der Schleife haben meine Vorposter schon genügend gesagt.
 
Ah okay verstehe, und wie könnte ich das lösen?

So bagbag geschrieben hat den Result auf die Form zu setzten?
 
Ich würde es genauso machen, wie mikasa vorgeschlagen hat:
Den Button disablen und in den OnCheck-Events der checkboxen jeweils die Bedingung überprüfen und wenn diese = TRUE ist, dann den Button erst enablen. Somit ist gewährleistet, dass dieser erst betätigt werden kann, wenn er auch eine Funktion hat.
 
Danke Jungs für die ganze Hilfe!

Ich habe es jetzt nach euren Ratschlägen so gelöst.

bntWeiter in den Eigenschaften "Enabled" = false gestellt und folgenden Code verwendet.

Code:
        private void cbx6Wochen_CheckedChanged(object sender, EventArgs e)
        {
            if (cbx6Wochen.Checked == true)
            {
                bntWeiter.Enabled = true;
            } 
            else
            {
                bntWeiter.Enabled = false;
            }
    
          
        }

        private void cbx6Monate_CheckedChanged(object sender, EventArgs e)
        {
            if (cbx6Monate.Checked == true)
            {
                bntWeiter.Enabled = true;
            }
            else
            {
                bntWeiter.Enabled = false;
            }
           
        }

        private void bntWeiter_Click(object sender, EventArgs e)
        {
          
            sechsWochen = cbx6Wochen.Checked;
            sechsMonate = cbx6Monate.Checked;
          }

So erhalte ich das Resultat was ich wollte, und dank euerer Hilfe ohne Schleife und ich habe wieder einiges dazu gelernt =)

Edit: Ich glaube so ist es noch etwas eleganter

Code:
 private void cbx6Wochen_CheckedChanged(object sender, EventArgs e)
        {
            if (cbx6Wochen.Checked == true) {
                bntWeiter.Enabled = true;
                cbx6Monate.Enabled = false;
              }
            else
            {
                cbx6Monate.Enabled = true;
                bntWeiter.Enabled = false;
            }
 
        }

        private void cbx6Monate_CheckedChanged(object sender, EventArgs e)
        {
            if (cbx6Monate.Checked == true)
            {
                cbx6Wochen.Enabled = false;
                bntWeiter.Enabled = true;
            }
            else 
            {
                cbx6Wochen.Enabled = true;
                bntWeiter.Enabled = false;
            }
          
          
        }

        private void bntWeiter_Click(object sender, EventArgs e)
        {

            sechsWochen = cbx6Wochen.Checked;
            sechsMonate = cbx6Monate.Checked;
        }
 
Zuletzt bearbeitet:
Zurück
Oben