Recientemente, hice algunas optimizaciones en el código. Después de la prueba, el efecto es bueno, pero descubrí que la interfaz parpadeará, específicamente el control TreeView parpadeará, el lenguaje es C # y el IDE es VS2005. Después de consultar cierta información y utilizar algunas técnicas básicas (como activar el doble almacenamiento en búfer), descubrí que no tuvo ningún efecto.
Entonces utilicé la herramienta PRfiler para descubrir que el cuello de botella radica en la operación EndUpdate después de actualizar la interfaz cada vez (esto se usa para reducir la cantidad de actualizaciones de la interfaz, pero no es ideal aquí porque hay muchos elementos en el control) Supongo que cada vez que se actualiza, la capa inferior de .Net. Cada primitiva se actualizará y se volverá a dibujar, por lo que la velocidad será lenta y provocará parpadeos. Pero si este es el caso, el uso de doble buffer debería dar mejores resultados. Al mirar el código nuevamente, descubrí que la acción de actualización podría ser demasiado frecuente, así que reduje la velocidad y mejoré, pero aún así no funcionó.
Continúe buscando en línea y finalmente encuentre una solución que sea más adecuada. Resulta que el redibujado subyacente borrará el lienzo cada vez y luego lo volverá a dibujar todo. Esta es la causa principal del parpadeo. Entonces la operación de la función de envío de mensajes está sobrecargada y este mensaje está deshabilitado. El código es el siguiente:
anulación protegida anular WndProc (mensaje de referencia m)
{
if (m.Msg == 0x0014) // Deshabilitar la eliminación de mensajes en segundo plano
devolver;
base.WndProc(ref m);
}
¡éxito!
Nota: El doble buffer sigue siendo útil cuando las actualizaciones no son muy frecuentes y el control no contiene demasiados elementos. Una vez que hay demasiados elementos, cada actualización llevará mucho tiempo. Incluso si se utiliza doble almacenamiento en búfer, el problema del parpadeo no se puede resolver. Personalmente, creo que el método ideal es desactivar y borrar los mensajes de fondo al final.
Adjunto: Algunos registros de intentos y fracasos
1) Utilice setStyle
Se dice en Internet que la función setStyle se utiliza para configurar los parámetros del control, específicamente:
SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, verdadero);
El último de estos tres parámetros de opción depende del primero y debe coexistir; de lo contrario, no será válido. Y esta función en sí está protegida, por lo que primero debes heredar un determinado control antes de usarla.
Este objetivo es consistente con la solución correcta anterior, que también deshabilita la limpieza del fondo y activa el doble almacenamiento en búfer, pero requiere la opción de dibujo del usuario, y todo el dibujo lo realiza el usuario. Esto requiere que usted mismo implemente todo el dibujo de los controles, lo cual es bastante problemático. Por lo tanto, este método no es completamente inviable, pero requiere trabajo adicional y no se recomienda. Yo tampoco lo usé.
2) Utilice BeginUpdate y EndUpdate
Este par de operaciones tiene un mejor efecto en escenarios donde se requieren operaciones por lotes para actualizar los controles, como agregar una gran cantidad de nodos en lotes durante la inicialización. La desventaja es que no se puede actualizar inmediatamente. Por lo tanto, no es adecuado para situaciones en las que los nodos se actualizan con frecuencia y desean reflejarse en la interfaz de inmediato. Si lo usa y no desactiva el mensaje claro de la interfaz, el control parecerá parpadear, tendrá principalmente un fondo blanco y el contenido será casi invisible (dependiendo de la complejidad del video). Debido a que las actualizaciones de la interfaz se completan en EndUpdate, demasiadas operaciones hacen que EndUpdate se bloquee durante mucho tiempo y la interfaz se borra primero y se actualiza más tarde, lo que hace que la interfaz aparezca en blanco durante mucho tiempo.
3) Utilice la opción ControlStyles.EnableNotifyMessage
El efecto de esta opción también es consistente con la solución correcta. El uso es:
SetStyle(ControlStyles.EnableNotifyMessage, verdadero);
anulación protegida anulada enNotifyMessage (Mensaje m)
{
//Escribe aquí el código del mensaje de filtro
}
Sin embargo, el experimento real no mostró ningún efecto, no sé por qué y no lo investigué en detalle.
-