2008-10-31 9 views
9

Tuvimos un problema de rendimiento con DataGridViews donde el redraw era terriblemente lento y encontramos la solución Here para crear un tipo derivado y habilitar el almacenamiento en búfer doble en el control. (El tipo derivado es necesario porque la propiedad DoubleBuffered está protegida)¿Por qué la propiedad DoubleBuffered es por defecto falsa en un DataGridView y por qué está protegida?

No parece que exista ningún inconveniente para tener la propiedad DoubleBuffered establecida en true.

Respuesta

1

El doble almacenamiento en memoria intermedia utiliza, por definición, dos almacenamientos intermedios y el doble de memoria para visualizar el control. Por lo tanto, hay un inconveniente allí, sin embargo, con la cantidad de memoria que obtienes en una PC ahora, no muchas personas probablemente notarían el sacrificio.

No tengo idea de por qué está protegido. Tal vez la función no estaba disponible en una versión anterior del control, y cuando se presentó, los diseñadores no quisieron cambiar la interfaz pública del control. O tal vez lo consideraron como una función avanzada y querían limitar el número de métodos que alguien nuevo en el control tendría que asimilar para poder hacer algo útil.

+1

Por qué la downvote? Es algo que he escrito incorrecto? –

15

Está protegido porque DGV hereda la propiedad de Control. Y Control.DoubleBuffered está protegido. Lo cual tiene sentido porque cada control derivado debería decidir por sí mismo activarlo. Y no tiene sentido que el usuario del control la active o desactive arbitrariamente. Los diseñadores de DGV decidieron desactivarlo.

Una razón por la que pueden haber decidido que es que el doble buffer realmente hace que la pintura sea más lenta. El paso adicional para renderizar el mapa de bits del buffer cuesta tiempo. Simplemente parece más rápido para el ojo humano, observa el mapa de bits que aparece de repente. No puede ver el tiempo que lleva dibujar en el mapa de bits. A menos que otros controles deban ser pintados y obtengan su turno después del DGV, entonces es bastante visible.

Lo que ves es la forma que se dibuja primero, con agujeros donde van los controles. Esos agujeros tienen un fondo blanco. Negro cuando usa la propiedad TransparencyKey u Opacity. Cada control recibe el evento Paint y los agujeros se llenan uno por uno. Ese efecto también se percibe como parpadeo por parte del usuario, aunque es un tipo diferente de parpadeo del que DoubleBuffered resuelve. Es especialmente notable cuando el fondo es negro.

Lo que se necesita para resolver este problema es que todo el formulario, con todos sus controles, tiene doble búfer. Eso no está disponible en Windows Forms. Sin embargo, Windows XP y versiones posteriores realmente lo soportan. Consulte this thread para ver cómo se hace eso. Tenga en cuenta que puede tener efectos secundarios según lo documentado en ese hilo.

+0

Interesante, aunque en el caso del datagridview, sin doublebuffering, toma 2-3 segundos para volver a dibujar el control, pero con doble buffering, aparece instantáneamente – Karg

+0

por cierto, hasta vote por la respuesta a la parte protegida de la pregunta – Karg

+2

En realidad el doble buffer hace que sea significativamente más rápido ... lo suficientemente rápido como para que a simple vista pueda diferenciarse.Aprecio esta respuesta porque puede ser lo más 'correcto', pero no es tan práctico como usar el reflejo para cambiar la configuración en DataGridView –

10

Creo que es mejor solución:

typeof(DataGridView).InvokeMember(
    "DoubleBuffered", 
    BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty, 
    null, 
    myDataGridViewObject, 
    new object[] { true }); 

encontró here

+3

La pregunta es preguntar por qué se establece en falso, no cómo anularlo. – Karg

+0

Aunque puede ser útil para alguien que está buscando cómo habilitar el doble buffer. – Barshan

Cuestiones relacionadas