none
Problema con filter en 2 datagridview RRS feed

  • Pregunta

  • Buenas, tengo un formulario con 2 datagridview, colocados en la pantalla, uno arriba y otro abajo.

    La idea, es que cuando yo selecciono una celda en el grid de arriba se me filtren los registros en el grid de abajo.

    Para ello en el CURRENTCELLCHANGED del grid de arriba tengo el siguiente código :

     TablarribaBindingSource.Filter =

    idbu = '"& DataGridView.CurrentRow.Cells(0).value& "'"

    Y el problema que tengo es que mientras cargo la aplicación recibo el error de : El código de usuario no controló nullrefernce exception.

    Entiendo que algún momento en el que se cargan las tablas, se produce que el campo sea null, ya que si en vez de en CURRENTCELLCHANGED lo pongo en el EVENTO CLICK, funciona perfectamente pero necesito actualizarlo cuando el usuario cambie de celda, no debería ser necesario hacer uso del raton.

    He intentado controlarlo mediante :

    if not string.isnullorempty(DataGridView.CurrentRow.Cells(0).value) ..

    o

    if DataGridView.CurrentRow.Cells(0).value is nothing

    Pero igualmente, me devuelve el mismo error en la línea del IF.

    Muchas gracias ;)

    domingo, 20 de enero de 2013 4:37

Respuestas

  • "mayoko" escribió:

    > Para ello en el CURRENTCELLCHANGED del grid de arriba tengo el
    > siguiente código :
    >
    > idbu = '"& DataGridView.CurrentRow.Cells(0).value& "'"
    >
    > Y el problema que tengo es que mientras cargo la aplicación recibo
    > el error de : El código de usuario no controló nullrefernce exception.
    >
    > Entiendo que algún momento en el que se cargan las tablas, se produce
    > que el campo sea null, ...

    Efectivamente, al estar enlazado el control DataGridView con un origen de datos, automáticamente se desencadena el evento CurrentCellChanged cuando se está cargando de datos el objeto DataTable subyacente, y como en dicho evento estás consultando el valor de la propiedad Cells de la propiedad CurrentRow del control DataGridView, al no existir actualmente una fila, el valor de la propiedad CurrentRow es Nothing, con lo cual, no puedes acceder a ninguna propiedad del objeto DataGridViewRow, que es el objeto que almacena la propiedad CurrentRow.

    Al comienzo del evento CurrentCellChanged tienes que verificar si la propiedad CurrentRow es o no Nothing, tal y como te muestro a continuación:

        Private Sub DataGridView1_CurrentCellChanged( _
            sender As Object, e As EventArgs) Handles DataGridView1.CurrentCellChanged
    
            ' ¿Existe alguna fila actualmente en el control DataGridView?
            '
            If (DataGridView1.CurrentRow Is Nothing) Then
                ' El valor de la propiedad CurrentRow es Nothing;
                ' abandonamos el procedimiento.
                Return
            End If
    
            ' Obtenemos el valor de la primera celda de la fila actual.
            '
            Dim value As Object = DataGridView1.CurrentRow.Cells(0).Value
    
            ' Si el valor es Nothing o DbNull.Value, abandonamos el procedimiento
            '
            If ((value Is Nothing) OrElse (value Is DBNull.Value)) Then
                Return
            End If
    
            ' En la variable 'value' tienes el valor de la primera celda.
            '
            MessageBox.Show(Convert.ToString(value))
    
        End Sub

    Como el valor de la propiedad es del tipo de dato Object, para convertirlo a String te aconsejo que utilices el método compartido ToString de la clase Convert (el que yo he utilizado en el ejemplo). Si el valor lo deseas convertir a otro tipo de dato diferente de String, entonces tienes que utilizar la función de conversión apropiada.

    Un saludo


    Enrique Martínez
      [MS MVP - VB]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, activa la instrucción Option Strict.



    domingo, 20 de enero de 2013 7:59
    Moderador

Todas las respuestas

  • "mayoko" escribió:

    > Para ello en el CURRENTCELLCHANGED del grid de arriba tengo el
    > siguiente código :
    >
    > idbu = '"& DataGridView.CurrentRow.Cells(0).value& "'"
    >
    > Y el problema que tengo es que mientras cargo la aplicación recibo
    > el error de : El código de usuario no controló nullrefernce exception.
    >
    > Entiendo que algún momento en el que se cargan las tablas, se produce
    > que el campo sea null, ...

    Efectivamente, al estar enlazado el control DataGridView con un origen de datos, automáticamente se desencadena el evento CurrentCellChanged cuando se está cargando de datos el objeto DataTable subyacente, y como en dicho evento estás consultando el valor de la propiedad Cells de la propiedad CurrentRow del control DataGridView, al no existir actualmente una fila, el valor de la propiedad CurrentRow es Nothing, con lo cual, no puedes acceder a ninguna propiedad del objeto DataGridViewRow, que es el objeto que almacena la propiedad CurrentRow.

    Al comienzo del evento CurrentCellChanged tienes que verificar si la propiedad CurrentRow es o no Nothing, tal y como te muestro a continuación:

        Private Sub DataGridView1_CurrentCellChanged( _
            sender As Object, e As EventArgs) Handles DataGridView1.CurrentCellChanged
    
            ' ¿Existe alguna fila actualmente en el control DataGridView?
            '
            If (DataGridView1.CurrentRow Is Nothing) Then
                ' El valor de la propiedad CurrentRow es Nothing;
                ' abandonamos el procedimiento.
                Return
            End If
    
            ' Obtenemos el valor de la primera celda de la fila actual.
            '
            Dim value As Object = DataGridView1.CurrentRow.Cells(0).Value
    
            ' Si el valor es Nothing o DbNull.Value, abandonamos el procedimiento
            '
            If ((value Is Nothing) OrElse (value Is DBNull.Value)) Then
                Return
            End If
    
            ' En la variable 'value' tienes el valor de la primera celda.
            '
            MessageBox.Show(Convert.ToString(value))
    
        End Sub

    Como el valor de la propiedad es del tipo de dato Object, para convertirlo a String te aconsejo que utilices el método compartido ToString de la clase Convert (el que yo he utilizado en el ejemplo). Si el valor lo deseas convertir a otro tipo de dato diferente de String, entonces tienes que utilizar la función de conversión apropiada.

    Un saludo


    Enrique Martínez
      [MS MVP - VB]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, activa la instrucción Option Strict.



    domingo, 20 de enero de 2013 7:59
    Moderador
  • Para ello en el CURRENTCELLCHANGED del grid de arriba tengo el siguiente código :

    porque usas ese evento, no es correcto, deberias usar el CellClick, o CellContentClick, para que sea una accion del usuario lo que seleccione la row del primer grid y genere el evento

    aconsejaria cambies el evento porque ese no es correcto, si lo haces veras como funcione


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    domingo, 20 de enero de 2013 11:37
  • "Leandro Tuttini" afirmó taxativamente:

    > porque usas ese evento, no es correcto, deberias usar el CellClick,
    > o CellContentClick, para que sea una accion del usuario lo que
    > seleccione la row del primer grid y genere el evento

    Y ¿por qué motivo no va a ser correcto? Si yo quiero hacer algo, lo que me venga en gana, cuando se modifica el valor de la propiedad CurrentCell del control DataGridView, SIN NINGUNA INTERVENCIÓN POR PARTE DEL USUARIO, ¿por qué no voy a poder beneficiarme del evento CurrentCellChanged?

    Aparte, si no fuera correcto, ¿por qué los ingenieros de Microsoft lo implementaron en la interfaz del control DataGridView? Con no haberlo implementado sería suficiente, y a lo mejor, posteriormente echaríamos de menos su inexistencia. :-D

     


    Enrique Martínez
      [MS MVP - VB]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, activa la instrucción Option Strict.



    domingo, 20 de enero de 2013 11:59
    Moderador
  • hace el comentario por esta linea:

    "es que cuando yo selecciono una celda en el grid de arriba se me filtren los registros en el grid de abajo"

    alli deja bien claro que es una interaccion con el usuario la que selecciona y produce el evento

    slaudos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    domingo, 20 de enero de 2013 12:23
  • "Leandro Tuttini" escribió:

    > "es que cuando yo selecciono una celda en el grid de arriba
    > se me filtren los registros en el grid de abajo"
    >
    > alli deja bien claro que es una interaccion con el usuario la
    > que selecciona y produce el evento

    ¡Bueno! Pero eso no es una respuesta convincente (o a menos a mí no me convence), para que tú afirmes taxativamente que "no es correcto" utilizar el evento CurrentCellChanged. Yo solamente te he preguntado el motivo para que tu afirmes que "no es correcto" usar dicho evento. ¡Nada más!

    Y ya puestos, también ha escrito el usuario lo siguiente:

    > pero necesito actualizarlo cuando el usuario cambie de celda,
    > no debería ser necesario hacer uso del raton.
    >

    Allí sí que deja bien claro el usuario mayoko que "no debería ser necesario hacer uso del ratón", por tanto, te vuelvo a repetir la pregunta: ¿por qué motivo dices que no es correcto utilizar el evento CurrentCellChanged? ¿En qué basas tu afirmación?

     


    Enrique Martínez
      [MS MVP - VB]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, activa la instrucción Option Strict.

    domingo, 20 de enero de 2013 12:31
    Moderador
  • Para Enrique M. Montejo:

    Creo yo que se le debería dar al usuario la opción de que filtre ya sea con el Evento CellClick o en su defecto usar el evento en MENCION, ya que algunos o la mayoria de usuarios suelen usar muy poco el raton del MOUSE.


    Luis Muñoz Hidalgo
    Mi Blog
    Desarrollador de Software
    Trujillo-Perú

    domingo, 20 de enero de 2013 12:44
  • "Luis F. Muñoz Hidalgo" escribió:

    > Creo yo que se le debería dar al usuario la opción de que filtre
    > ya sea con el Evento CellClick o en su defecto usar el evento en
    > MENCION, ya que algunos o la mayoria de usuarios suelen usar muy
    > poco el raton del MOUSE.

    Pues por ese motivo, ¿por qué no va a ser correcto hacer uso del evento CurrentCellChanged? Digo yo que para algo lo inventaron.

    Si yo lo único que quiero es que Leandro Tuttini nos explique a todos, los motivos en los se basa para afirmar que "no es correcto" utilizar el evento CurrentCellChanged. ;-)


    Enrique Martínez
      [MS MVP - VB]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, activa la instrucción Option Strict.

    domingo, 20 de enero de 2013 12:55
    Moderador
  • De acuerdo contigo al 100% compañero Enrique. Al usuario no se le puede restringir a usar solo el Mouse. 

    Se le debe dar flexibilidad usar las dos opciones.

    Saludos desde Perú.


    Luis Muñoz Hidalgo
    Mi Blog
    Desarrollador de Software
    Trujillo-Perú

    domingo, 20 de enero de 2013 12:58
  • como comente me base en las siguiente:

    - por la linea que marque en donde se comenta la interaccion con el usuario, y es este quien debe decidir que linea quiere seleccionar, el ir navegando por las rows no implcia que debe cambiar el otro grid relacionado, salvo cuando el usuario lo solicita aplicar

    - porque si revisamos la documentacion

    DataGridView.CellClick (Evento)

    el click tambien se acciona por teclado, usando la barra espaciadora, ai que ese argumento de teclado o mouse no aplica, porque funciona con ambos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    domingo, 20 de enero de 2013 13:24
  • "Leandro Tuttini" escribió:

    > - por la linea que marque en donde se comenta la interaccion con el
    > usuario, y es este quien debe decidir que linea quiere seleccionar,
    > el ir navegando por las rows no implcia que debe cambiar el otro
    > grid relacionado, salvo cuando el usuario lo solicita aplicar

    Pero insisto que eso no tiene nada que ver con que tú afirmes que "no es correcto" usar el evento CurrentCellChanged. ¡Vamos! Que me he quedado lo mismo que estaba cuando he leído por primera vez la afirmación realizada.

    De todas maneras, yo lo seguiré usando cuando estime que es necesario para hacer esto o aquello, porque que yo sepa, no tiene nada de malo utilizar el evento CurrentCellChange del control DataGridView, máxime si queremos ejecutar algo sin la participación del usuario, aunque obviamente hay que saber utilizarlo, al igual que también hay que saber cómo utilizar otras cosas. :-D


    Enrique Martínez
      [MS MVP - VB]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, activa la instrucción Option Strict.


    domingo, 20 de enero de 2013 14:04
    Moderador
  • hola

    tego este codigo...tal vez te pueda servir de ayuda

     Private Sub DataGridView1_CellDoubleClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellDoubleClick

            Dim row As DataGridViewRow = DataGridView1.CurrentRow()

            If row Is Nothing Then
                MessageBox.Show("SELECCIONE FILA")
                Return
            End If

            Try
                    If (row.Cells("DOC_RDA_RQ").Value IsNot DBNull.Value) Then
                        Dim PONUMBER As String
                        PONUMBER = Str(row.Cells("DOC_RDA_RQ").Value)
                        SQL = "SELECT CAST(PONUMBER AS INT) As DOC_RDA_RQ ,REQDATE As Fecha, (ORD/16384) As Linea ,ITEMNMBR As CodigoArticulo, ITEMDESC As Descripcion,VENDORID As Proveedor,VNDITNUM As CodigoServicio,INVINDX As CodigoInv,UOFM As UnidadMedida,CAST(QTYORDER AS INT) As Cantidad,UNITCOST As PrecioUnidad,EXTDCOST As CostoTotal,CURNCYID As Moneda FROM POP10110 WHERE PONUMBER =@PONUMBER ORDER BY PONUMBER ASC"
                        Dim Clase As Compras = New Compras()
                        resultado = Clase.PruebaConexion2()
                        If (resultado) Then
                            Dim dataTabla As DataTable = New DataTable()
                            dataTabla.Clear()
                            DataGridView2.DataSource = dataTabla
                            dataTabla = Clase.DetalleOrdenCompra(SQL, PONUMBER)
                            DataGridView2.DataSource = dataTabla
                            DataGridView2.Visible = True : BtnX.Visible = True
                        End If
                    End If

            Catch ex As Exception
                MessageBox.Show("ERROR 0001-E2")
            End Try

        End Sub


    EFRAIN MEJIAS C VALENCIA - VENEZUELA

    domingo, 20 de enero de 2013 14:13
  • JEJEJE madreee miaaa! la que se ha liado, sin animo de ofender a nadie os daré mi humilde opinión de novel programadora en VB.net.

    Ante todo, dar las gracias a enrique pues el código me funciona perfectamente y de principio lo voy a dejar así ;)

    Solo me gustaría una una cuestión sobre el código, y es que veo en muchas códigos que asignais todo a variables, que mas da poner :

           Dim value As Object = DataGridView1.CurrentRow.Cells(0).Value       
           
    If ((value Is Nothing) OrElse (value Is DBNull.Value)) Then

    que poner :

    If ((DataGridView.CurrentRow.Cells(0).Value Is Nothing) OrElse (DataGridView.CurrentRow.Cells(0).Value Is DBNull.Value)) Then

    Ahora, os daré mi opinión sobre todo lo comentado,  basándome para ello en mi pobre experiencia sin tener en cuenta al detalle muchas otros factores que vosotros seguro si podríais tener :

    Para mi, el principal motivo de usar el currentcellchanged fue que me resulta rápido, el evento se ejecuta tanto si muevo con el teclado como si muevo con el raton, es cierto que podría hacer lo mismo con los eventos click y keyup pero tengo que escribir mas código por ejemplo para comprobar si la tecla que presiono es arriba o abajo en el keypress.

    Otro punto a favor del currentcellchanged , es que ese evento se produce también automáticamente, me explico, como decía anteriormente tengo 2 datagridview el segundo datagridview varia en función de lo que selecciono en el primero, pero los datos del primero también varian en función del albarán que selecciono, por lo tanto, cuando selecciono otro albarán, se actualiza el datagridview1 y por ende lo hace también DE FORMA AUTOMATICA el datagridview2. Sin el currentcellchanged esto tendría que programarlo.

    En favor, de la respuesta de Leandro, pues a lo mejor tampoco tiene mucha lógica estar actualizando continuamente el datagridview de abajo, dado que si estoy en un mismo row y me muevo por las diferentes columnas con el currentcellchanged estoy ejecutando continuamente el código de filtrado y actualización del datagridview de abajo.

    Analizado todo esto, entiendo que para el uso concreto de mi código viene perfecto el currentcellchanged.

    En cualquier caso agradezco todas vuestras opiniones.

    • Editado mayoko domingo, 20 de enero de 2013 16:11 me confundi en pegar codigo
    domingo, 20 de enero de 2013 16:09
  • "mayoko" preguntó:

    > Solo me gustaría una una cuestión sobre el código, y es que veo
    > en muchas códigos que asignais todo a variables, que mas da poner :
    >
    >  Dim value As Object = DataGridView1.CurrentRow.Cells(0).Value      
    >  If ((value Is Nothing)  OrElse (value Is DBNull.Value)) Then
    >
    > que poner :
    >
    > If ((DataGridView.CurrentRow.Cells(0).Value Is Nothing) OrElse
    > (DataGridView.CurrentRow.Cells(0).Value Is DBNull.Value)) Then

    Da igual utilizar un código u otro porque los dos son correctos y "corren" igual de rápido; la diferencia digamos que se encuentra en la CLARIDAD y CONCISIÓN del código escrito.

    A mí me gusta más definir variables locales simplemente porque el código se lee mejor, ya que queda una constancia más clara del tipo de dato que devuelve la propiedad o función llamada.

    Aparte, imagina que en el mismo procedimiento tienes que hacer varios usos del valor de la propiedad Cells. Como el valor ya lo tienes en la variable (cuyo nombre normalmente suele ser mucho más corto), no tienes que estar escribiendo largas líneas de código, como por ejemplo, DataGridView.CurrentRow.Cells(0).Value.

    Y esas variables locales declaradas no impactan en el rendimiento de la aplicación, y no consumen más memoria de la que ya pueda consumir el objeto que se va a consultar, porque al fin de cuentas lo que hacen es REFERENCIAR un objeto o valor que ya está en memoria. Si hablamos de un valor escalar, al finalizar el procedimiento se destruirá automáticamente la variable.

    Pero en fin, comprendo que es cuestión de gustos. ;-)

    > Para mi, el principal motivo de usar el currentcellchanged fue que
    > me resulta rápido, el evento se ejecuta tanto si muevo con el
    > teclado como si muevo con el raton, ...

    Pues eso es lo que yo digo, por tanto, ¿por qué no va a ser correcto utilizar el evento CurrentCellChanged? ;-)


    Enrique Martínez
      [MS MVP - VB]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, activa la instrucción Option Strict.



    domingo, 20 de enero de 2013 16:40
    Moderador