2016-05-12 5 views
0

Ich möchte eine Schaltfläche deaktivieren, sobald ein Benutzer darauf klickt, um sie erneut zu klicken. Es gibt eine Reihe von Überprüfungen, die ausgeführt werden, wenn sie darauf klicken, und es scheint, dass diese Überprüfungen durchgeführt werden, bevor die UI-Änderung stattfindet.Wie aktualisiere ich ein UI-Element in WPF, bevor ich den Rest einer Funktion verarbeite?

Ich versuche, dies zu tun, indem Sie einen separaten Thread für die Schaltfläche verwenden, aber es scheint immer noch nur nach den Überprüfungen zu aktualisieren.

Hier ist der Code ich verwende:

private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    Thread t = new Thread(new ThreadStart(
    delegate 
    { 
     Action action =() => btnStart.IsEnabled = false; 
     Dispatcher.BeginInvoke(action); 
    } 
    )); 
    t.Start();   
    // Run the main routine; 
    BeginBootstrapping(); 
} 

Wie kann ich den Knopf sofort deaktivieren?

+0

Zuerst deaktivieren Sie die Schaltfläche wie üblich, dann führen Sie _the Rest_ auf Hintergrund Thread. Keine Notwendigkeit, die Schaltfläche im Hintergrund-Thread zu deaktivieren (es funktioniert nicht einmal). – Evk

Antwort

0
private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    btnStart.IsEnabled = false 
    Thread t = new Thread(new ThreadStart(
    delegate 
    { 
     // Run the main routine; 
     BeginBootstrapping(); 
    })); 

    t.Start(); 
} 

Wie Evk sagte in seinem Kommentar, das die Schaltfläche rechts vom UI-Thread Hauptthread) deaktiviert, dann läuft den Rest von dem, was auf dem anderen Thread getan werden. Hinweis: Ich verwende den Dispatcher nicht, da der Dispatcher auch der UI-Thread ist und die UI dadurch eingefroren wird.

+0

Nur um zu bemerken, dass Sie nur den neuen Thread brauchen, wenn 'BeginBootStrapping()' sowieso keinen erstellt (ansonsten ist es ein wenig verschwenderisch). Es kann sich lohnen, "BackgroundWorker" anstelle von rohen Threads in Betracht zu ziehen, da es den Fortschritt und die Completion-Callbacks zurück auf den UI-Thread führt, vorausgesetzt, Sie benötigen diese natürlich. – Paolo

4

Sie können einen async Click-Handler schreiben, die eine Task verwendet einige Hintergrundinformationen Arbeit auszuführen:

using System.Threading.Tasks; 
... 

private async void Button_Click(object sender, RoutedEventArgs e) 
{ 
    var button = (Button)sender; 
    button.IsEnabled = false; 

    await Task.Run(() => DoTheBootstrapping()); 

    button.IsEnabled = true; 
} 

Natürlich, wenn Sie die lange Lauf Methode selbst awaitable wie

machen
private async Task DoTheBootstrapping() 
{ 
    var httpClient = new HttpClient(); 
    var content = await httpClient.GetStringAsync("http://stackoverflow.com"); 
} 

können Sie es ohne Task.Run wie

anrufen
+0

Wenn dies so ist - besser DoTheBootstrapping async selbst statt Task.Run machen. – Evk

+0

@Evk Sicher, wenn möglich. Was ist, wenn in DoTheBootstrapping kein Aufruf erwartet wird? Das Codebeispiel soll auch eine Alternative zum manuellen Erstellen eines Threads zeigen. – Clemens

+0

Nun, Sie haben Recht, ich hätte eher sagen sollen, dass es eine solche Option gibt, nicht dass es immer so gemacht werden sollte. Wenn es jedoch zu erwartende Anrufe gibt - besser async machen. – Evk

Verwandte Themen