Trabajar con doble buffer en un Panel

Generalmente cuando trabajo con gráficos suelo pintar sobre el área cliente de la propia ficha, pero esta vez he tenido que hacerlo por narices en un panel.


Activar el sistema de doble buffer de una ficha es muy sencillo, tenemos que cambiar su estilo y aplicarlo. Algo así: 



this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint,true);
this.UpdateStyles();


El primer valor de ControlStyles indica que se va a activar el doble buffer, el segundo que se genere un evento de pintado cuando se redimensione el panel (este valor no es obligatorio pero me hace falta a mi),  y el tercero que todo el pintado se va a realizar en evento Paint (habitualmente el sistema primero pinta el fondo automáticamente en otro evento y luego llama al de pintado).


Pero lo que con una ficha es algo trivial con un Panel es imposible ya que dichos métodos son protegidos y no tenemos acceso a ellos. La solución políticamente correcta consiste en heredar del panel para tener acceso a los miembros protegidos del mismo, pero entonces quitamos la posibilidad de trabajar en el editor visual (a no ser que te crees un componente propio basado en un panel, pero es casi peor el remedio que la enfermedad).


Pero como el menda es bastante políticamente incorrecto, buscando por aquí y por allí ha encontrado un método alternativo mucho más fácil que el anterior, método que consiste en llamar a dichas funciones protegidas mediante el uso de la reflexión (y aquí es donde uno agradece ciertos aspectos del .NET):


 



//Activating DoubleBuffer techniques. We must do it with reflection because Panel.SetStyle is a protected member.
MethodInfo m=typeof(Panel).GetMethod(«SetStyle»,System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
Object[] parameters=new Object[2];
parameters[0]=
new ControlStyles();
parameters[0]=
ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint;
parameters[1] =
new bool();
parameters[1] =
true;
m.Invoke(m_pnlGuachindeil, parameters);
m =
typeof(Panel).GetMethod(«UpdateStyles», System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
m.Invoke(m_pnlGuachindeil,
null);


Siendo justos deberíamos controlar si el valor de m es válido, pero como este código va prefijado si algo falla es que debemos terminar, así que dejamos la salida, el lanzamiento de la excepción y la captura de la misma al sistema (eso si lo hace, cosa que no siempre ocurre como hemos podido ver en alguna entrada anterior).

4 comentarios sobre “Trabajar con doble buffer en un Panel”

Responder a anonymous Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *