Laden...

Button ändert Farbe nicht in der Laufzeit

Erstellt von Noob6666 vor 5 Jahren Letzter Beitrag vor 5 Jahren 1.784 Views
N
Noob6666 Themenstarter:in
17 Beiträge seit 2018
vor 5 Jahren
Button ändert Farbe nicht in der Laufzeit

Hallo Zusammen,

ich hab das Forum durchsuchst aber leider nichts gefunden.

Vorab JA ich weiß wie man die Hintergrundfarbe eines Buttons ändern, ich möchte nur verstehen warum er es nicht
zur Laufzeit macht, sondern erst wenn meine Funktion die aufgerufen wird,komplett beendet ist.



        private void buttonRun_Click(object sender, EventArgs e)
        {
              if (buttonRun.BackColor == Color.Red)
              {
                  ChangeColor(0);
              }
              else if (buttonTowerRun.BackColor == Color.LimeGreen)
              {
                  ChangeColor(1);
              }
                Start();//Probiert das über ein Delegate zu fixem                
                Thread.Sleep(1000);  

                Settings = new Settings ();
                a.führeFunktionaus();

        }

        void ChangeColor(int P)
        {
            if (P==0)
            {

                buttonRun.BackColor = Color.LimeGreen;
                buttonRun.ForeColor = Color.Black;
                
            }
            if (P==1)
            {
                buttonRun.BackColor = Color.Red;
                buttonRun.ForeColor = Color.White;
            }
        }

hab alles mögliche ausprobiert, auch über ein delegate meine Funktion zu starten und nicht über einen direkten Aufruf aus dem KlickEvent , switch
statt den if anweisungen (je verzweifelter , desto komplexer die methoden 😄) aber nix hat funktioniert, der Button verändert die Farbe erst,
wenn die komplette Funktion durchgespielt wird, Wenn ich eine MessageBox in meiner Funktion einbaue,völlig egal wo sie steht,wird die Farbe des Buttons geändert
ohne das die funktion komplett durchlaufen muss, detailierter kann ich das ganze leider ned beschreiben.

Hab versucht zu googlen ob es Prioritäten zu vergeben gibt , aber hab da nix gefunden

Weiß einer weiter???

LG Nooob

5.658 Beiträge seit 2006
vor 5 Jahren

Hi Noob6666,

die Benutzeroberfläche kann nicht aktualisiert werden, solange eine Berechnung im UI-Thread läuft, in deinem Fall Thread.Sleep. Für längerdauernde Vorgänge gibt es den BackgroundWorker. Der arbeitet die Berechnungen im Hintergrund ab, und die UI bleibt bedienbar.

Siehe auch: [FAQ] Warum blockiert mein GUI?

Weeks of programming can save you hours of planning

709 Beiträge seit 2008
vor 5 Jahren

Für längerdauernde Vorgänge gibt es den BackgroundWorker. Der arbeitet die Berechnungen im Hintergrund ab, und die UI bleibt bedienbar.

Dann wirst du zusätzlich [FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke) benötigen.

4.938 Beiträge seit 2008
vor 5 Jahren

@pinki: das gilt aber nicht für die ProgressChanged und RunWorkerCompleted-Ereignishandler, denn diese laufen automatisch im UI-Thread, s.a. Beispiel in BackgroundWorker Class.

709 Beiträge seit 2008
vor 5 Jahren

Danke für den Hinweis.
Ist schon 'ne Weile her. Da hatte ich das falsch in Erinnerung.

2.079 Beiträge seit 2012
vor 5 Jahren

Weil Links ja erfahrungsgemäß weniger verwendet werden als genannte Stichworte:

Heute verwendet man Tasks anstatt BackgroundWorker, der Code wird dadurch deutlich einfacher und lesbarer.
Vielleicht gibt es noch Situationen, wo BackgroundWorker die bessere Option sind, mir ist aber keine bekannt.

Also lieber mal nach Tasks, "async" oder "await" suchen, da gibt mehr als genug Hilfen und Tutorials im Internet und die Lernkurve ist mMn. sehr viel angenehmer - zumindest solange man darauf vertrauen kann und will, dass .NET im Hintergrund seine Magie tut 😄

16.828 Beiträge seit 2008
vor 5 Jahren

async/await ist aber kein vollständiger Ersatz für das Auslagern von langwierigen Operationen.
Gewisse Dinge können damit umgesetzt werden (zB. asynchrone Dateioperationen, siehe BackgroundWorker und modale Dialoge); für langwierige Operationen ist dennoch ein eigener Thread (zB durch Task.Run()) notwendig.

N
Noob6666 Themenstarter:in
17 Beiträge seit 2018
vor 5 Jahren

sorry für die verspätete Antwort, als Schüler ist man leider nicht so flexibel 😁

vielen dank für die Hilfestellungen, habe einige Wege gefunden wie man das umgehen kann

Lösung 1:



            private async void button1_Click(object sender, EventArgs e)
            {                    
                  if (button1_Click.BackColor == Color.Red)
                  {//nach den Threadeinträgen im Debugging werden beide Funktionen in separate Threads ausgefürt und nicht im Hauptthread
                    await Task.Run(() => AndereKlasse.machIwas());
                    ChangeColor(0);    
                  }
                  else if (button1_Click.BackColor == Color.LimeGreen)
                  {
                      ChangeColor(1);
                  }           
            }



Lösung 2:

persönliche mein Favorit weil
viel schneller quasi beim loslassen der Taste wird ausgefürt
Einfacher in der Struktur (bin Anfänger da muss man sich nicht alles so schwer machen 😄)


            private void button1_Click(object sender, EventArgs e)
            {                    
                ChangeColor(0);

                Thread T1= new Thread(() =>
                {
                    AndereKlasse.machIwas());
                });
                T1.Start();
                  else if (button1_Click.BackColor == Color.LimeGreen)
                  {
                      ChangeColor(1);
                  }           
            }



Multithreating is auf jeden Fall ein Thema mit dem man sich befassen muss.
Vielen dank nochmal für die Denkanstöße!!!

LG Noob

16.828 Beiträge seit 2008
vor 5 Jahren

Die Lösung 2 sollte man in diesem Fall nicht verwenden.
Der Task (hinter async/await) nimmt einem viel an manuellem Thread-Handling ab und bietet dazu noch eine State Machine und Kontext-Zugriff auf die UI; zudem erfolgt keine Allocation beim Erstellen eines Tasks.

Deine Begründung bzgl. Schnelligkeit kann technisch nicht stimmen.
Und einfacher ist es für Dich nur, weil Du die Nachteile nicht siehst - weil Dir eben der Unterschied von Task und Thread unbekannt sind.

Generell in .NET: vermeide manuelles Thread-Handling, wenn Du mit Tasks arbeiten kannst.
Threads haben sehr viele Nachteile gegenüber Tasks, was den Code selbst betrifft.

Task.Run arbeitet ebenfalls mit einem extra Thread, was asynchrone Programmierung nicht zwangsläufig tut; nimmt Dir aber das gesamte Thread-Handling ab (was Dir in Lösung 2 komplett fehlt).
Das Task.Run ist prinzipiell auch nicht notwendig, wenn Deine "MachIrgendWas"-Methode korrekt asynchron zur Verfügung steht.

Es ist wichtig, dass Du weisst was ein Thread ist und was ein Task ist, dass ein Task immer mit einem Thread arbeitet; aber Du wirst in .NET heutzutage nur sehr selten mit der Thread-Klasse zutun haben müssen.
Das nimmt Dir alles das Framework und async/await bzw. Tasks ab - und das ist auch gut so.