Laden...

Runtime Button gibt nach Klick NULL aus und lässt sich nicht unvisible stellen

Erstellt von Zagrthos vor 2 Jahren Letzter Beitrag vor 2 Jahren 414 Views
Z
Zagrthos Themenstarter:in
5 Beiträge seit 2021
vor 2 Jahren
Runtime Button gibt nach Klick NULL aus und lässt sich nicht unvisible stellen

Guten Abend,

ich hätte ein kleines Problem in meinem Programm.

Momentan bin ich dabei die Forms auf ein TableLayoutPanel umzustellen, um diese responsiver zu gestalten.
Dabei habe ich auf einer Form einen Button1, welcher bei dem Klick darauf durch Button2 ersetzt wird und wenn Button2 geklickt wird, wieder durch Button1 ersetzt.

Ohne das TLP hatte das wunderbar funktioniert, mit dem TLP hingegen bekomme ich den Button zwar ersetzt jedoch funktioniert der Wechsel zwischen Button2 und Button1 nicht mehr.
Das Ganze endet in folgender Exception:

Fehlermeldung:
System.NullReferenceException: 'Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.'
btnSwitchBack was null.

Der Code des ganzen ist folgender:


// Event zum Aufrufen des Wechsels
private void btnSwitch_Click(object sender, EventArgs e)
        {
            btnSwitch.Visible = false;
            CreateButton();
        }

// Der Wechsel selbst
private void CreateButton()
        {
            Button btnSwitchBack = new Button
            {
                Dock = DockStyle.Fill,
                Location = btnSwitch.Location,
                Margin = btnSwitch.Margin,
                Name = "btnSwitchBack",
                Size = btnSwitch.Size,
                Text = "Test-Text",
                UseVisualStyleBackColor = true,
                Enabled = true,
            };
            Controls.Add(btnSwitchBack);
            DesignISR.Controls.Add(btnSwitchBack, 0, 7); // Das TLP
            btnSwitchBack.Visible = true;
            btnSwitchBack.Click += new EventHandler(btnSwitchBack_Click);
        }

// Der Wechsel zurück
private void btnSwitchBack_Click(object sender, EventArgs e)
        {
            Button btnSwitchBack = (Button)Controls["btnSwitchBack"];
            btnSwitchBack.Visible = false; // Hier tritt der Fehler immer auf
            btnSwitch.Visible = true;
        }

Ich habe bisher schon versucht das ganze hin und her zu schieben und im Debugger zu schauen was der Wert des Buttons ist aber so richtig funktioniert hat das nicht.
Der Wert des Buttons, nachdem er aus der Methode CreateButton() herauskommt, ist immer der mitgelieferte Text. Am Ende jedoch ist der Button wieder NULL.

Habt ihr vielleicht weitere Lösungsvorschläge?
Der Code hat vor dem Umstieg auf die TLP noch funktioniert - oder hab ich schlicht was vergessen?

Danke für die Antworten!

J
61 Beiträge seit 2020
vor 2 Jahren

Was spricht gegen ein simples Wiederbenutzen des btnSwitch Buttons?

Den aktuellen Zustand kannst du in einem Boolean Flag hinterlegen und bei jedem Klick entsprechend ändern.

So etwas wie


bool isSwitchBackVisible;

private void btnSwitch_Click(object sender, EventArgs e)
        {
            if(isSwitchBackVisible)
                 btnSwitch.Text = „Text“;
            else
                 btnSwitch.Text = „Test-Text“;
            isSwitchBackVisible = ! isSwitchBackVisible;
        }


2.079 Beiträge seit 2012
vor 2 Jahren

Oder einfach den "sender"-Parameter casten, das sollte der Button sein.

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

4.939 Beiträge seit 2008
vor 2 Jahren

Hallo,

warum es jetzt nicht mehr funktioniert liegt an den beiden Zeilen


Controls.Add(btnSwitchBack);
DesignISR.Controls.Add(btnSwitchBack, 0, 7); // Das TLP

Ein Control (d.h. hier der Button) kann nur genau einem anderen Container-Control untergeordnet sein (= einen Parent haben). Durch die 2. Zeile wird der Button aber dem TableLayoutPanel zugeordnet und daher verschwindet es wieder aus der Controls-Auflistung der Form und das Auslesen daraus ergibt null (und daher die entsprechende Exception beim Zugriff darauf).

Wie Palladin007 schon geschrieben hat, einfach den sender casten (dies sollte man generell bei den Eventhandlern so machen):


var btnSwitchBack = sender as Button;
// ...

Z
Zagrthos Themenstarter:in
5 Beiträge seit 2021
vor 2 Jahren

So ich habe die letzten Stunden damit verbracht das ganze etwas anzupassen.

Dabei habe ich den Rat von Jompikumpi befolgt und das schlussendlich in einem Button mitsamt einer if Abfrage gelöst. Ich habe wohl zu komplex gedacht und eine "falsche" Lösung ausgesucht.

Danke an alle für die Antworten und auch Danke an Th69 für die Erklärung des Fehlers. Damit lässt sich das in Zukunft hoffentlich vermeiden. 🙂