2010-02-18 14 views
19

Tengo un código que permite arrastrar una forma sin bordes en winforms que llevo usando desde hace varios meses, que funciona muy bien.Invalidar vs Actualizar

Pero cuando me dieron el código por primera vez, usaron this.Invalidate(); en el evento MouseMove de la Forma, y ​​la Forma parpadeó un poco y fue lenta al arrastrarla. Por lo tanto, reemplacé Invalidate() con Update() en el evento MouseMove y, para mi sorpresa, ahora se puede arrastrar el Formulario sin problemas y no parpadea en absoluto.

¿Alguien puede explicarme por qué Update hace que el código funcione mejor que Invalidar, incluso cuando Invalidate parece que es el correcto para usar?

Gracias :)

P. S. Tal vez sería más útil si añadiera el código ... Agregándolo ahora.

Editar - Aquí está el código:


private void titlebar_MouseDown(object sender, MouseEventArgs e) 
{ 
    this.IsMouseDown = true; 

    this.LastCursorPosition = new Point(e.X, e.Y); 

    if (this.BackColor == Color.White) 
    { 
     this.BackColor = Color.GhostWhite; 
     tbox.BackColor = Color.GhostWhite; 
     tbox.ForeColor = Color.Black; 
    } 
    else 
    { 
     this.BackColor = Color.FromArgb(20, 20, 20); 
     tbox.BackColor = Color.FromArgb(20, 20, 20); 
     tbox.ForeColor = Color.White; 
    } 
} 

private void titlebar_MouseMove(object sender, MouseEventArgs e) 
{ 
    if (this.IsMouseDown == true) 
    { 
     //Move the form 
     this.Location = new Point(this.Left - (this.LastCursorPosition.X - e.X), this.Top - (this.LastCursorPosition.Y - e.Y)); 

     // Update works better than Invalidate();. 
     Update(); 
    } 
} 

private void titlebar_MouseUp(object sender, MouseEventArgs e) 
{ 
    this.IsMouseDown = false; 
    this.BackColor = fc; 
    tbox.BackColor = fc; 
} 

Respuesta

12

Invalidate marca la ventana como la necesidad de que se actualice (en algún momento). Actualización hace allí y luego, si no recuerdo mal

Aquí es una link para explicar la diferencia mejor de lo que sería capaz de

+2

Gracias un montón Martin. :) –

31

Invalidate() simplemente añade una región a la región de actualización del control. La próxima vez que se reciba WM_PAINT, el área invalidada más cualquier otra región invalidada se marcan para pintar. Cuando se llama al RedrawWindow(), normalmente se publicará un mensaje WM_PAINT en la cola de la aplicación. El sistema es libre de hacer lo que quiera con eso, generalmente más urgente, y pintar cuando puede.

Si llama Update(), se obtiene GDI + 's UpdateWindow() que no marcará una región para el repintado, pero empuja un WM_PAINT directamente a WNDPROC(), sin pasar por la cola de la aplicación.

Si necesita una actualización inmediata de un control, utilice Refresh(), lo que invalida la región inmediatamente llama Update().

+0

Me doy cuenta de que esta es una publicación anterior y quizás esto debería publicarse como una pregunta separada, pero no tengo claro cuándo usaría Actualizar y cuándo utilizaría Actualizar. Parece que ambos fuerzan un repintado inmediato. ¿Eres capaz de aclarar? ¡Gracias! –

+4

@ AdamPlocher A partir de los comentarios del método, parece que 'Invalidate()' simplemente indica que la región requiere pintura, pero no pinta necesariamente. 'Update()' obliga a repintar las regiones actualmente no válidas, pero no marca nada. Y 'Refresh()' ajusta las dos operaciones juntas, primero marcando la región del control como inválida y luego solicitando que la región se actualice (repintada). ** Editar: ** http://stackoverflow.com/a/952964/1718702 – HodlDwon