2011-11-14 5 views
7

lungo in esecuzione Quando si dispone di un pulsante, e fare qualcosa di simile:Forza ridisegno prima delle operazioni

Private Function Button_OnClick 

    Button.Enabled = False 

    [LONG OPERATION] 

End Function 

Poi il pulsante non verrà visualizzato in grigio, perché la lunga operazione impedisce il thread UI da ridipingere il controllo. So che il design giusto è quello di avviare un thread in background/dispatcher, ma a volte è troppo complicato per una semplice operazione.

Quindi, come posso forzare il pulsante per ridisegnare in stato disabilitato? Ho provato .UpdateLayout() sul pulsante, ma non ha avuto alcun effetto. Ho anche provato System.Windows.Forms.DoEvents() che normalmente funziona quando si usano WinForms, ma non ha avuto alcun effetto.

risposta

8

Il codice seguente farà ciò che stai cercando. Comunque non lo userei. Utilizzare la classe BackgroundWorker per operazioni prolungate. È facile da usare e molto stabile.
Qui il codice:

public static void ProcessUITasks() {    
     DispatcherFrame frame = new DispatcherFrame(); 
     Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new DispatcherOperationCallback(delegate(object parameter) { 
      frame.Continue = false; 
      return null; 
     }), null); 
     Dispatcher.PushFrame(frame); 
    } 

Here troverete un esempio su come utilizzare il BackgroundWorker.

+0

Era abbastanza chiaro di essere a conoscenza ma non usare un Dispatcher/Backgroundworker :) – edvaldig

+2

@edvaldig: Ho sottolineato di non usarlo, tuttavia gli ho dato il codice che cercava. Non penso che questo valga un -1 da te. Se il mio codice non funziona, dammi un -1, ma non per dare qualche consiglio in più. Non penso sia giusto. – HCL

+1

Hai ragione, ero troppo veloce a questo proposito, commento upvote per compensare :) – edvaldig

0

InvalidateVisual(); @HCL ha ragione ... non farlo

Come dici tu, è meglio iniziare a utilizzare un thread in background/dispatcher e mantenere il thread dell'interfaccia utente sbloccato. Considerare lo Reactive Extensions library da Microsoft per la programmazione dell'interfaccia utente asincrona di alto livello

+0

Questo non funzionerà. L'invalidazione invalida solo la regione da ridipingere. Comunque non dipinge. – HCL

+0

@HCL, Funziona bene per me, vedere la documentazione per la funzione: Invalida il rendering dell'elemento e forza un nuovo passaggio di layout completo. OnRender viene chiamato dopo il completamento del ciclo di layout. – edvaldig

+0

Sei sicuro che la tua interfaccia utente è bloccata? L'ho provato l'ultima volta con .net3.5SP1. In questo momento non ha funzionato. Se funziona ora, devono aver cambiato il comportamento con 4.0. Tuttavia, questa sarebbe una grande sorpresa per me. – HCL

0

In Windows.Forms, è possibile Button.Refresh().

In Windows.Forms o WPF, è possibile arrendersi al pump dei messaggi per consentirne il ridisegno. Async/Await sono stati progettati per permetterti di fare questo senza la cattiveria della risposta di HCL.

Private Async Function Button_OnClick 

    Button.Enabled = False 

    Await Task.Yield 

    [LONG OPERATION] 

End Function