elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: AIO elhacker.NET 2021 Compilación herramientas análisis y desinfección malware


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP) (Moderador: kub0x)
| | | |-+  [C#] DataGridView congelación de app
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: [C#] DataGridView congelación de app  (Leído 3,041 veces)
kondrag_X1

Desconectado Desconectado

Mensajes: 157


Ver Perfil
[C#] DataGridView congelación de app
« en: 10 Junio 2015, 10:15 am »

Hola,

El problema es el siguiente: inserto filas en un datagridview y cuando llega a un determinado número de filas se queda la app congelada y el scroll vertical no aparece si no que hace algo raro. Además tengo la propiedad ScrollBar en Vertical.

Personalmente no sé que puede estar pasando quizas un problema de la interfaz .... ni idea. He estado buscando por internet y a la gente este componente no suele darle muchos problemas.

¿Se os ocurre que puede estar pasando?

#########################
Ya aparece el scroll era simplemente que tenia la propiedad AutoSize = true; y claro había que ponerla a false. Pero el problema sigue existiendo cuando aparece el scroollBar la app se queda congelada.


« Última modificación: 10 Junio 2015, 10:26 am por kondrag_X1 » En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.810



Ver Perfil
Re: [C#] DataGridView congelación de app
« Respuesta #1 en: 10 Junio 2015, 11:02 am »

Si estás utilizando el método DataGridView.Rows.Add que toma cómo argumento el número de filas a crear, entonces el thread de la UI no se podrá actualizar hasta que finalice dicha operación de inserción de filas, por ende, la UI se congelará.

Habría que ver el código para poder comprobar el qué y cómo lo estás haciendo, ya que quizás haya otros problemas que estén derivando en esa congelación del thread, así que si no das más datos no se te puede ayudar a buscar la solución más eficiente para el problema que sea en cuestión.

De todas formas, puedes añadir las filas de manera asíncrona para solventar el problema de congelación, pero esto tomará bastante más tiempo en añadir todas las filas:

Código
  1. Public Class Form1
  2.  
  3.    Private WithEvents bgw As New BackgroundWorker
  4.  
  5.    Private Sub Button1_Click(sender As Object, e As EventArgs) _
  6.    Handles Button1.Click
  7.  
  8.        DataGridView1.ColumnCount = 1
  9.        bgw.RunWorkerAsync()
  10.  
  11.    End Sub
  12.  
  13.    Sub DoRowAdd(ByVal dgv As DataGridView, ByVal row As DataGridViewRow)
  14.  
  15.        If dgv.InvokeRequired Then
  16.            dgv.Invoke(Sub() dgv.Rows.Add(row))
  17.  
  18.        Else
  19.            dgv.Rows.Add(row)
  20.  
  21.        End If
  22.  
  23.    End Sub
  24.  
  25.    Sub Work(ByVal sender As Object, ByVal e As EventArgs) _
  26.    Handles bgw.DoWork
  27.  
  28.        For rowIndex As Integer = 0 To Short.MaxValue
  29.  
  30.            Dim row As New DataGridViewRow
  31.            row.Cells.Add(New DataGridViewTextBoxCell With {.Value = rowIndex})
  32.            Me.DoRowAdd(Me.DataGridView1, row)
  33.  
  34.        Next rowIndex
  35.  
  36.    End Sub
  37.  
  38. End Class

Otra alternativa sería añadir las filas una a una cómo en el ejemplo anterior, pero utilizando el método Application.DoEvents para que tras cada inserción se procese el resto de mensajes (eventos) en cola para actualizar la UI;
el tiempo que se toma en crear las filas es practicamente el mismo que en el ejemplo de arriba.

Código
  1.        DataGridView1.Columns.Add(String.Empty, String.Empty)
  2.  
  3.        For rowIndex As Integer = 0 To Short.MaxValue
  4.  
  5.            DataGridView1.Rows.Add({rowIndex})
  6.            Application.DoEvents()
  7.  
  8.        Next rowIndex

También lo que puedes hacer al utilizar el método DataGridView.Rows.Add que toma cómo argumento el número de filas a crear, es suspender la lógica del layout del control, esto aceleraría bastante el tiempo que tarda en agregar todas las filas, pero obviamente no se desbloquearía la UI.

Código
  1.        DataGridView1.Columns.Add(String.Empty, String.Empty)
  2.        DataGridView1.SuspendLayout()
  3.        DataGridView1.Rows.Add(Short.MaxValue)
  4.        DataGridView1.ResumeLayout()



EDITO: Ups, perdón, no me di cuenta que lo preguntaste en C#, aquí tienes una conversión online:

Código
  1. using Microsoft.VisualBasic;
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Data;
  6. using System.Diagnostics;
  7. public class Form1
  8. {
  9.  
  10. private BackgroundWorker withEventsField_bgw = new BackgroundWorker();
  11. private BackgroundWorker bgw {
  12. get { return withEventsField_bgw; }
  13. set {
  14. if (withEventsField_bgw != null) {
  15. withEventsField_bgw.DoWork -= Work;
  16. }
  17. withEventsField_bgw = value;
  18. if (withEventsField_bgw != null) {
  19. withEventsField_bgw.DoWork += Work;
  20. }
  21. }
  22. }
  23.  
  24. private void Button1_Click(object sender, EventArgs e)
  25. {
  26.  
  27. DataGridView1.ColumnCount = 1;
  28. bgw.RunWorkerAsync();
  29.  
  30. }
  31.  
  32. public void DoRowAdd(DataGridView dgv, DataGridViewRow row)
  33. {
  34.  
  35. if (dgv.InvokeRequired) {
  36. dgv.Invoke(() => dgv.Rows.Add(row));
  37.  
  38. } else {
  39. dgv.Rows.Add(row);
  40.  
  41. }
  42.  
  43. }
  44.  
  45. public void Work(object sender, EventArgs e)
  46. {
  47.  
  48. for (int rowIndex = 0; rowIndex <= short.MaxValue; rowIndex++) {
  49.  
  50. DataGridViewRow row = new DataGridViewRow();
  51. row.Cells.Add(new DataGridViewTextBoxCell { Value = rowIndex });
  52. this.DoRowAdd(this.DataGridView1, row);
  53.  
  54. }
  55.  
  56. }
  57.  
  58. }
  59.  
  60. //=======================================================
  61. //Service provided by Telerik (www.telerik.com)
  62. //=======================================================

Considero que los otros dos ejemplos no necesitan una conversión a C# para entenderlos.

Saludos!


« Última modificación: 10 Junio 2015, 11:12 am por Eleкtro » En línea

kondrag_X1

Desconectado Desconectado

Mensajes: 157


Ver Perfil
Re: [C#] DataGridView congelación de app
« Respuesta #2 en: 10 Junio 2015, 14:01 pm »

muchismas gracias Electro voy a probarlo a ver si eso me puede solucionar el problema. Además haciendo pruebas he visto que es cuando inserto fila con "DataGridView.Rows.Add" y se completa el datagrid ocurre esto. Creo que es tema del sincronismo voy a probarlo y os comento.

saludos.
En línea

kondrag_X1

Desconectado Desconectado

Mensajes: 157


Ver Perfil
Re: [C#] DataGridView congelación de app
« Respuesta #3 en: 11 Junio 2015, 09:56 am »

Hola de nuevo,

Sinceramente no sé por que ocurre esto: Cuando intento visualizar mas elementos que el tamaño del datagridView no aparece la barra vertical y además la app se queda bloqueada. Estoy implementando tu código adaptandolo pero me da un error diciendo que no se puede convertir una expresión lambda en un System.Delegate. Entiendo lo que me quiere decir pero no se me ocurre como implementarlo.

por ejemplo así: Teniendo un delegado que llame a mi método.

Código
  1. private void updateVisualizacionMatricula(String texto)
  2.        {
  3.            if (this.InvokeRequired)
  4.            {
  5.                updateVisualizacionMatricula_ d = new updateVisualizacionMatricula_(updateVisualizacionMatricula);
  6.                this.Invoke(d, new object[] { texto });
  7.            }
  8.            else
  9.            {
  10.                lb_visualizacionMatricula.Text = texto;
  11.                int x = groupBoxVisualizacion.Width + label29.Width;
  12.                int w = lb_visualizacionMatricula.Width;
  13.                lb_visualizacionMatricula.Left = x / 2 - w / 2;
  14.            }
  15.        }
  16.  


 A y otra cosa ¿Cómo podría pasar los distintos parámetros al método InsertarFila en el método work?

Código
  1. public void InsertarFilaDescarga(String modelo,
  2.                                        String calidad,
  3.                                        String color,
  4.                                        String talla,
  5.                                        String TotalTeorica,
  6.                                        String TotalReal,
  7.                                        String lote)
  8.        {
  9.            //Creamos fila;
  10.            DataGridViewRow row = new DataGridViewRow();
  11.            DataGridViewButtonColumn buttonColumn = new DataGridViewButtonColumn();
  12.            buttonColumn.UseColumnTextForButtonValue = true;
  13.  
  14.            row.Cells.Add(new DataGridViewTextBoxCell { Value = modelo });
  15.            row.Cells.Add(new DataGridViewTextBoxCell { Value = calidad});
  16.            row.Cells.Add(new DataGridViewTextBoxCell { Value = color });
  17.            row.Cells.Add(new DataGridViewTextBoxCell { Value = talla });
  18.  
  19.            if (lote.Equals("x1"))
  20.            {
  21.                row.Cells.Add(new DataGridViewButtonCell { Value = "x1" });
  22.            }
  23.            else if (lote.Equals("x2"))
  24.            {
  25.                row.Cells.Add(new DataGridViewButtonCell { Value = "x2" });
  26.            }
  27.            else
  28.            {
  29.                row.Cells.Add(new DataGridViewTextBoxCell { Value = "" });
  30.                //dGV_Descarga.Rows.Add(new object[] { modelo,  calidad, color, talla,
  31.                //    null,TotalTeorica,TotalReal});
  32.  
  33.                //var cell = dGV_Descarga.Rows[dGV_Descarga.RowCount - 1].Cells[4] = new DataGridViewTextBoxCell();
  34.                //cell.Value = "";
  35.                //cell.ReadOnly = true;
  36.            }
  37.  
  38.            row.Cells.Add(new DataGridViewTextBoxCell { Value = TotalTeorica });
  39.            row.Cells.Add(new DataGridViewTextBoxCell { Value = TotalReal });
  40.  
  41.            //insertamos fila
  42.            if (dGV_Descarga.InvokeRequired)
  43.            {
  44.                 dGV_Descarga.Invoke(() => dGV_Descarga.Rows.Add(row));
  45.            }
  46.            else
  47.            {
  48.                dGV_Descarga.Rows.Add(row);
  49.            }
  50.        }
  51.  
  52.        public void InsertarFilaDescarga(DataGridView dg , DataGridViewRow row)
  53.        {
  54.            if (dg.InvokeRequired)
  55.            {
  56.  
  57.                 dg.Invoke(() => dg.Rows.Add(row));
  58.  
  59.            }
  60.            else
  61.            {
  62.                dg.Rows.Add(row);
  63.            }
  64.        }
  65.  
« Última modificación: 11 Junio 2015, 17:42 pm por Eleкtro » En línea

kondrag_X1

Desconectado Desconectado

Mensajes: 157


Ver Perfil
Re: [C#] DataGridView congelación de app
« Respuesta #4 en: 11 Junio 2015, 17:56 pm »

al final lo conseguí mañana lo comentaré y pondré el código.
En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.810



Ver Perfil
Re: [C#] DataGridView congelación de app
« Respuesta #5 en: 11 Junio 2015, 18:05 pm »

Mi manejo en C# no es muy bueno.

Puedes declarar el delegado:
Código
  1. internal delegate void UpdateVisualizacionMatriculaDelegate(string texto);
  2.  
  3. private void updateVisualizacionMatricula()
  4. {
  5. if (this.InvokeRequired) {
  6. this.Invoke(new UpdateVisualizacionMatriculaDelegate(updateVisualizacionMatricula), texto);
  7.  
  8. } else {
  9. lb_visualizacionMatricula.Text = texto;
  10. int x = groupBoxVisualizacion.Width + label29.Width;
  11. int w = lb_visualizacionMatricula.Width;
  12. lb_visualizacionMatricula.Left = x / 2 - w / 2;
  13. }
  14. }
  15.  
  16. //=======================================================
  17. //Service provided by Telerik (www.telerik.com)
  18. //=======================================================

O también puedes usar el delegado Action para evitar la declaración de delegados adicionales en el código

Código
  1. this.Invoke(new Action<string>(updateVisualizacionMatricula), texto)
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines