2011-11-14 10 views
7

larga duración Cuando se tiene un botón, y hacer algo como:Fuerza volver a dibujar antes de las operaciones

Private Function Button_OnClick 

    Button.Enabled = False 

    [LONG OPERATION] 

End Function 

entonces no se muestran en gris el botón, debido a la operación a largo evita que el hilo de interfaz de usuario vuelva a dibujar el control. Sé que el diseño correcto es iniciar un hilo de fondo/despachador, pero a veces eso es demasiada molestia para una operación simple.

Entonces, ¿cómo fuerzo el botón para volver a dibujar en estado deshabilitado? Intenté .UpdateLayout() en el botón, pero no tenía ningún efecto. También probé System.Windows.Forms.DoEvents() que normalmente funciona cuando se usa WinForms, pero tampoco tuvo efecto.

Respuesta

8

El siguiente código hará lo que está buscando. Sin embargo, no lo usaría. Use la clase BackgroundWorker para operaciones prolongadas. Es fácil de usar y muy estable.
Aquí el código:

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 encontrará una muestra de cómo usar el BackgroundWorker.

+0

Tenía bastante claro que era consciente pero no usaba un Dispatcher/Backgroundworker :) – edvaldig

+2

@edvaldig: He subrayado que no debo usarlo, sin embargo le he dado el código que estaba buscando. No creo que esto valga un -1 de ti. Si mi código no funciona, entonces dame un -1, pero no para dar algunos consejos adicionales. No creo que esto sea justo. – HCL

+1

Tienes razón, fui demasiado rápido al respecto, comento el comentario para compensar :) – edvaldig

0

InvalidateVisual(); @HCL es correcto ... no haga esto

Como usted dice, es mejor comenzar a usar un hilo de fondo/despachador y mantener el hilo de la UI desbloqueado. Considere mirar el Reactive Extensions library de Microsoft para la programación de la interfaz de usuario asíncrona de alto nivel

+0

Esto no funcionará. La invalidación solo invalida la región para ser repintada. Sin embargo, no es la pintura. – HCL

+0

@HCL, funciona bien para mí, consulte la documentación de la función: anula la representación del elemento y fuerza un nuevo pase de diseño completo. Se llama a OnRender una vez que se completa el ciclo de diseño. – edvaldig

+0

¿Estás seguro de que tu UI-thread está bloqueado? Lo he probado la última vez bajo .net3.5SP1. En este momento no funcionó. Si funciona ahora, deben haber cambiado el comportamiento con 4.0. Sin embargo, esto sería una gran sorpresa para mí. – HCL

0

En Windows.Forms, puede Button.Refresh().

En Windows.Forms o WPF, puede ceder el mensaje a la bomba para que se vuelva a dibujar. Async/Await fueron diseñados para permitirte hacer esto sin la maldad de la respuesta de HCL.

Private Async Function Button_OnClick 

    Button.Enabled = False 

    Await Task.Yield 

    [LONG OPERATION] 

End Function 
Cuestiones relacionadas