Hola.
como realizo tal operación que me indicas?
( Me tomo la libertad de responderte yo, que hace tiempo que no respondo nada en el foro, y el compañero
NEBIRE parece estar un poco ausente a este thread. )
Al decir "deshabilitar un control" yo al menos me estoy refiriendo a deshabilitar las peticiones de redibujado del control. ¿Y cómo se hace esto?... pues depende del escenario...
Si es un control que realice un layout automático, por lo general un contenedor de controles como:
TableLayoutPanel,
FlowLayoutPanel, o
Panel, podemos utilizar el método
Control.SuspendLayout(), esto es útil sobre todo al añadir muchos controles al contenedor de controles, ahí queremos suprimir el layout para que el control no se redibuje hasta que hayamos terminado de insertar todos los controles. La supresión del layout afecta a propiedades tales como:
Control.AutoSize,
Control.Anchor y
Control.Dock. Podemos ignorar llamar a
SuspendLayout claro está, pero de hacerlo solo conseguiremos que el proceso de inserción /interacción con el control sea lento y feo, produciendo flickering...
Si por lo contrario hablamos de un un control de usuario entonces es mucho más facil "deshabilitar" el control ya que evidentemente tendriamos toda la capacidad de controlar el dibujado del control a nivel interno digamos. Por decir algo: podría ser tan simple como anular (
override) la propiedad
Control.Enabled e ignorar todo el dibujado del control mientras su valor sea
False, por ejemplo.
Para un control de tipo lista, es decir:
ListView,
ListBox o
ComboBox, lo que debemos hacer es llamar al método
Control.Beginpdate. Los pasos a seguir serian los siguientes:
...Las operaciones de interacción con la colección (Control.Items) del control aquí...
Con el método
Control.BeginUpdate() lo que conseguimos hacer es suprimir cualquier petición de redibujado durante las modificaciones que le hagamos a la colección del control. Cada vez que añadimos un elemento a la colección, se dispara un evento para que el control se redibuje, esto por cada 1 de los elementos que añadamos en el control, por lo tanto resulta evidente que pretender añadir varios elementos a la colección sin preocuparnos del redibujado... provocará una considerable disminuición en el rendimiento del control.
Sin embargo el control
DataGridView no expone dicho miembro, pero en su lugar... (sigue leyendo aquí abajo)
Hay que reconocer que el sistema es un poco tonto, porque si se añade al final y el elemento no cabe en la vista, no hace falta en realidad actualizar la vista.... pero...
Así es, pero precisamente para solventar ese problema de raíz es que está la propiedad
DataGridView.VirtualMode (con su posterior y tediosa implementación personal):
Ese es el modo más óptimo de administrar la respuesta o "responsividad" de un control
DataGridView con exceso de elementos (como los +14.000 en este caso).
De todas formas, para mantener una velocidad de respuesta estable en un
DataGridView en la carga de varios elementos, para evitar el redibujado constante y mantener un rendimiento decente, vaya, tampoco es tan dificil, por lo general no debería ser necesario recurrir a implementar el modo virtual, sino que simplemente debemos utilizar un
DataSource en lugar de administrar manualmente la cantidad de columnas y filas, y la inserción o eliminación manual de elementos. Que de eso se encargue la lógica del control por si solo mediante el
DataSource bindeado. Pero lo cierto es que no he trabajo en escenarios con +14.000 elementos de carga, así que no puedo hablar mucho de lo que no he experimentado...
Eso sí, si por el motivo que sea nos vemos obligados a tener que administrar de forma manual la inserción de elementos en el
DataGridView (como parece ser tu caso), entonces para aumentar el rendimiento se debe utilizar el método
DataGridView.Rows.AddRange en lugar de
DataGridView.Rows.Add (recuerda que por cada elemento añadido el control se redibujará... y no quieres que eso ocurra, así que debes añadir todos los elementos de una sola vez, llamando a
AddRange).
Para el tema de las búsquedas... una solución sería dejar un margen de tiempo de inactividad, un "timeout" por así decirlo. En lugar de buscar cada vez que presionas una tecla, lo que debes hacer es determinar (mediante un objeto Timer o StopWatch) cuanto tiempo hace que se pulsó una tecla por última vez (digamos 500 milisegundos, es un buen valor de inactividad), y entonces empezar a realizar la búsqueda en los elementos de la colección. O más sencillo: realizar la búsqueda solamente cuando se presione la tecla ENTER, o al presionar un botón que diga "Buscar".
Saludos.