none
Maestro-Detalle RRS feed

  • Pregunta

  • Estoy tratando de optimizar mis formularios de maestro-detalles, tengo este codigo para el maestro


    Public Class frmArticulos
        Inherits FrmAheredar

        Dim Titulo As String = "Articulos"
        Dim spSelectDgv As String = "ArticulosSelectDgv"

        Private Sub frmArticulos_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Me.Text = Titulo
            'Permisos()

            GeneralBindingSource.DataSource = DataTableFill(spSelectDgv)
            Dim filterManager As New DgvFilterManager(dgvGrilla)
            With dgvGrilla
                .Width = 400
                Me.Width = .Width + 10
                .DataSource = GeneralBindingSource
                .Columns("ArticuloID").Visible = False
                .FormatoColumna("CodigoQS", TiposColumna.Miles, 92, 1)
                .FormatoColumna("Descripcion", TiposColumna.Izquierda, 300, 2)
                .FormatoGeneral()
            End With

            'Hacer visible los botones que tienen visible = False en frmaHeredar
            butExcel.Visible = True

        End Sub

        Overrides Sub Insertar()
            Action("Insertar")
            GeneralBindingSource.MoveLast()
        End Sub

        Overrides Sub Modificar()
            Action("Modificar")
        End Sub

        Overrides Sub Ver()
            Action("Ver")
        End Sub

        Overrides Sub Eliminar()
            If ConfirmarBorrado() Then DeleteArticulos(dgvGrilla.CurrentRow.Cells("ArticuloID").Value)
            GeneralBindingSource.DataSource = DataTableFill(spSelectDgv)
        End Sub

        Overrides Sub ToExcel()
            ExportToExcel("Many", Me.Text, dgvGrilla)
        End Sub

        Overrides Sub ToWord()
            ExportToWord("Many", Me.Text, dgvGrilla)
        End Sub

        Private Sub Action(ByVal TipoAction As String)
            Dim DBO_Articulo As New DBO_Articulos
            Dim m_Pos As Integer = GeneralBindingSource.Position

            If TipoAction = "Insertar" Then
                'Asignar las propiedades del objeto creado cuyos valores se obtengan en este Form.
            Else
                DBO_Articulo = spArticulos.Select_Record(GeneralBindingSource(m_Pos).Item("ArticuloID"))
            End If

            Dim frmEnt As New frmEntArticulos(DBO_Articulo, m_Pos)
            frmEnt.Text = String.Format("{0} {1}", TipoAction, Titulo)
            frmEnt.ShowDialog()
            'DBO_Articulo = frmEnt.GetValues
            GeneralBindingSource.DataSource = DataTableFill(spSelectDgv)
        End Sub

        Private Sub dgvGrilla_MouseDoubleClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles dgvGrilla.MouseDoubleClick
            Modificar()
        End Sub
    End Class

     

     

    Y para el detalle


    Public Class frmEntArticulos
        Inherits FrmAHeredarEnt

        Private m_Pos As Integer
        Private DBO_Articulo As DBO_Articulos

        Public Sub New(ByRef Articulo As DBO_Articulos, ByVal Pos As Integer)
            InitializeComponent()
            DBO_Articulo = Articulo
            m_Pos = Pos
        End Sub

        Private Sub frmEntArticulos_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            ModificarBindingNavigator()

            If (Me.Text.Substring(0, 3) = "Ver") Then
                GeneralBindingSource.DataSource = DataTableFill("ArticulosSelectAll")
                GeneralBindingSource.Position = m_Pos
            End If

            SetValores()
        End Sub

        Private Sub SetValores()
            txtArticuloID.Text = DBO_Articulo.ArticuloID
            txtCodigoQS.Text = IIf(DBO_Articulo.CodigoQS_IsDBNull = True, Nothing, DBO_Articulo.CodigoQS)
            txtDescripcion.Text = IIf(DBO_Articulo.Descripcion_IsDBNull = True, Nothing, DBO_Articulo.Descripcion)
        End Sub

        Private Sub GetValores()
            DBO_Articulo.CodigoQS = System.Convert.ToInt32(IIf(txtCodigoQS.Text = "", Nothing, txtCodigoQS.Text))
            DBO_Articulo.CodigoQS_IsDBNull = IIf(txtCodigoQS.Text = "", True, False)
            DBO_Articulo.Descripcion = System.Convert.ToString(IIf(txtDescripcion.Text = "", Nothing, txtDescripcion.Text))
            DBO_Articulo.Descripcion_IsDBNull = IIf(txtDescripcion.Text = "", True, False)
            DBO_Articulo.FechaModificacion = System.DateTime.Now
            DBO_Articulo.FechaModificacion_IsDBNull = False
            DBO_Articulo.UsuarioModificacion = gUsuarioID
            DBO_Articulo.UsuarioModificacion_IsDBNull = False
        End Sub

        Overrides Sub Guardar()
            GetValores()
            If (Me.Text.Substring(0, 3) = "Ins") Then
                InsertArticulos(DBO_Articulo)
            Else
                UpdateArticulos(DBO_Articulo.ArticuloID, DBO_Articulo)
            End If
            Me.Close()
        End Sub

        Overrides Sub MoveRecord(ByVal Move As String)
            Select Case Move
                Case Is = "First"
                    m_Pos = 0
                Case Is = "Previous"
                    m_Pos -= 1
                Case Is = "Next"
                    m_Pos += 1
                Case Is = "Last"
                    m_Pos = GeneralBindingSource.Count - 1
            End Select
            GeneralBindingSource.Position = m_Pos
            DBO_Articulo = spArticulos.Select_Record(GeneralBindingSource(m_Pos).Item("ArticuloID"))
            SetValores()
        End Sub

        'Public ReadOnly Property GetValues() As DBO_Articulos
        '    Get
        '        ' Devolvemos el objeto
        '        Return DBO_Articulo
        '    End Get
        'End Property

    End Class

     

    He estado revisando anteriores preguntas, y he llegado a un articulo de Enrique Martinez "Como pasar datos a un formulario" en la que recomienda pasar el row seleccionado en el formulario maestro al formulario detalle.

    En mi caso en lugar de pasar el row paso un objeto, porque puede que existan propiedades de este objeto que no estén contenidas en las columnas del DataGridView al no estar incluidas en la consulta que se usa para rellenar los datos.

    Se que podria ocultar las columnas que no me interesen mostrar, pero considero que el codigo es mas limpio asi.

    El problema es que una vez que he editado los valores en el detalle la unica forma que encuentro para que estos cambios se recojan el el DataGridView maestro es

    volver a realizar la consulta

    GeneralBindingSource.DataSource = DataTableFill(spSelectDgv)

    He intentado seguir los consejos de Enrique y devolver el objeto, pero no se como hacer para que los cambios se reflejen.

    Me gustaria conseguir que solo tuviese que refrescar el row utilizado ¿Es posible hacerlo?

     

    Os agradecer cualquier sugerencia para mejorar mi codigo ademas de lo tratado en esta pregunta.

     

    Gracias por vuestra colaboración.


    Miguel Angel Martinez correomam@gmail.com
    • Editado mam01 domingo, 19 de diciembre de 2010 10:33
    domingo, 19 de diciembre de 2010 10:01

Respuestas

  • > Desde el maestro si se ve que han cambiado las propiedades del
    > objeto pasado, lo veo usando el msgbox,
    >

    Entonces el problema ya no es del formulario Detalle, porque éste modifica los valores del objeto pasado a su constructor.

    > El problema sigue siendo que no consigo refrescar la grilla.
    >
    >    Private Sub Action(ByVal TipoAction As String)
    >
    >        Dim DBO_Articulo As New DBO_Articulos
    >        Dim m_Pos As Integer = GeneralBindingSource.Position
    >
    >        If TipoAction = "Insertar" Then
    >            'Asignar las propiedades del objeto creado cuyos valores se obtengan en este Form.
    >        Else
    >            DBO_Articulo = spArticulos.Select_Record(GeneralBindingSource(m_Pos).Item("ArticuloID"))
    >        End If
    >
    >       Using frmEnt As New frmEntArticulos(DBO_Articulo, m_Pos)
    >
    >            frmEnt.Text = String.Format("{0} {1}", TipoAction, Titulo)
    >
    >            frmEnt.ShowDialog()
    >
    >            DBO_Articulo = frmEnt.GetValues
    >
    >        End Using
    >
    >        'GeneralBindingSource.DataSource = DataTableFill(spSelectDgv)
    >
    >    End Sub

    ¿Y tampoco se refresca mediante el método ResetBindings?

        GeneralBindingSource.ResetBindings(True)

    ¡No sé! Entiendo que una vez se cierre el formulario Detalle y llames a dicho método, se debería de refrescar la "grilla". ¿?

    Fijándonos en el código del método Action, creas una nueva instancia por defecto de la clase DBO_Articulos:

         Dim DBO_Articulo As New DBO_Articulos

    la cual es la que se utilizará cuando el TipoAction sea igual a "Insertar". Si el parámetro es distinto a "Insertar", a la variable objeto declarada le estás asignando el valor devuelto por el método Select_Record, el cual devolverá un objeto de acuerdo a los valores de los parámetros pasados. Si ese objeto devuelto es del tipo DBO_Articulos, entiendo que será el objeto que se modificará cuando llames al formulario Detalle.

    De todas maneras, si por "grilla" entendemos un control DataGridView, lo correcto entiendo que es referenciar el objeto DataGridViewRow, que representará la fila seleccionada actualmente en el control, tal y como así aparece en mi artículo, porque tú lo que estás referenciando es un objeto del tipo DBO_Articulos, que obviamente es distinto de un objeto DataGridViewRow, aunque éste contenga los valores del objeto DBO_Articulos. Si tu intención es refrescar la "grilla", tendrás que asignar nuevamente la propiedad DataSource del control BindingSource, siempre y cuando la "grilla" se encuentra enlazada al mencionado control.

    Si deseas hacer una prueba, en lugar de referenciar el objeto que se encuentra en una posición concreta del control BindingSource, referencia la fila actual del control DataGridView, y al formulario Detalle le pasas ese objeto DataGridViewRow. Obviamente, tendrás que incluir una nueva sobrecarga en el contructor del formulario Detalle para que acpete dicho objeto, y trabajar con ese objeto. Como se está trabajando con la lista subyacente enlazada al control BindingSource, los cambios serán automáticos, o al menos eso es lo que dice la teoría. :-)

    Por cierto

    > GeneralBindingSource(m_Pos).Item("ArticuloID")

    Ese control llamado GeneralBindingSource, ¿es alguna clase que has diseñado para que herede de la clase BindingSource?

    Si la respuesta es negativa, ¿tienes activada la preceptiva instrucción Option Strict?

     


    Enrique Martínez
      [MS MVP - VB]

    • Marcado como respuesta mam01 domingo, 19 de diciembre de 2010 19:31
    domingo, 19 de diciembre de 2010 12:24
    Moderador

Todas las respuestas

  • Miguel Ángel, ¿podrías editar el código fuente que has publicado? Pégalo antes en el Bloc de Notas, y desde ahí lo copias y lo pegas finalmente en el mensaje. Como observarás, no se entiende nada. :-)

    No obstante, si te has fijado en el ejemplo de mi artículo, estamos hablando de objetos por referencia (la clase DataGridViewRow), que se pasa al segundo formulario (digamos el formulario Detalle):

            ' Referenciamos la fila.
            '
            Dim row As DataGridViewRow = DataGridView1.CurrentRow

    Y antes de eliminar la variable objeto que referencia al segundo formulario, obtenemos el valor de la propiedad GetValues existente en dicho formulario, la cual devuelve un objeto DataGridViewRow que posteriormente se lo asignamos a la variable objeto que referencia la fila del control DataGridView, es decir, la variable anteriormente declarada:

            If (dlg = DialogResult.OK) Then
                 ' Obtenemos los nuevos valores.
                 row = frm.GetValues
            End If

    Como estamos trabajando con objetos por referencia, los cambios se efectuarán de una manera automática.

    Lo mismo es lo que estás haciendo, pero no consigo verlo tal y como aparece publicado en tu mensaje, por lo que sería conveniente que lo editaras.


    Un saludo y ¡Feliz Navidad!


    Enrique Martínez
      [MS MVP - VB]

    domingo, 19 de diciembre de 2010 10:18
    Moderador
  • Ahora que has formateado un poco mejor el código fuente, no observo que la clase frmEntArticulos devuelva un objeto del tipo DBO_Articulos, que es lo que se espera que haga.

    Prueba a insertar en la clase frmEntArticulos la siguiente propiedad pública, la cual la tienes comentada:

        Public ReadOnly Property GetValues() As DBO_Articulos
            Get
                ' Devolvemos el objeto
                Return DBO_Articulo
            End Get
        End Property

    Y cuando llames a dicha clase desde el procedimiento Action de la clase frmArticulos, ejecutarías lo siguiente:

        Private Sub Action(ByVal TipoAction As String)

            Dim DBO_Articulo As New DBO_Articulos
            Dim m_Pos As Integer = GeneralBindingSource.Position

            If TipoAction = "Insertar" Then
                'Asignar las propiedades del objeto creado cuyos valores se obtengan en este Form.
            Else
                DBO_Articulo = spArticulos.Select_Record(GeneralBindingSource(m_Pos).Item("ArticuloID"))
            End If

            Using frmEnt As New frmEntArticulos(DBO_Articulo, m_Pos)

                frmEnt.Text = String.Format("{0} {1}", TipoAction, Titulo)

                ' Mostramos el formulario detalle.
                '
                Dim dlg As DialogResult = frmEnt.ShowDialog()

                If (dlg = DialogResult.OK) Then

                    ' Obtenemos los nuevos valores.
                    DBO_Articulo = frmEnt.GetValues

                End If

            End Using

            GeneralBindingSource.DataSource = DataTableFill(spSelectDgv)

        End Sub

    Eso es exactamente lo que explico en el artículo, que el segundo formulario o clase tiene que devolver un valor, bien en un método público del tipo Function o a través de una propiedad pública de sólo lectura.

     


    Enrique Martínez
      [MS MVP - VB]

    domingo, 19 de diciembre de 2010 10:35
    Moderador
  • Lo he editado creo que ahora se vera mejor, la verdad es que estaba intentando utilizar la utilidad de pegar codigo, pero veo que no funciona demasiado bien, o yo no se hacerlo.

    Me dices que estamos trabajando con objetos por referencia, pero lo que yo hago es trabajar con

      Private DBO_Articulo As DBO_Articulos

    al que asigno el objeto pasado por referencia

     Public Sub New(ByRef Articulo As DBO_Articulos, ByVal Pos As Integer)
            InitializeComponent()
            DBO_Articulo = Articulo
            m_Pos = Pos
        End Sub

    Como todos los cambios los hago sobre DBO_Articulo no hay actualizacion automatica.

    ¿Tendria que asignar todo sobre Articulo sin utilizar DBO_Articulo?

    Gracias, y ¡Feliz Navidad!


    Miguel Angel Martinez correomam@gmail.com
    domingo, 19 de diciembre de 2010 10:41
  • Las lineas que me comentas si estan en el codigo inicial, aunque comentadas ya que no consigo que la grilla refleje los cambios hechos en el detalle, la unica solucion es

    GeneralBindingSource.DataSource = DataTableFill(spSelectDgv)

    ¿No hay forma de refrescar la fila afectada por los cambios?

     

     

     


    Miguel Angel Martinez correomam@gmail.com
    domingo, 19 de diciembre de 2010 10:54
  • > Lo he editado creo que ahora se vera mejor, la verdad es que estaba
    > intentando utilizar la utilidad de pegar codigo, pero veo que no funciona
    > demasiado bien, o yo no se hacerlo.

    Sí, de vez en cuando también da sus problemas. Yo prefiero escribir todo el mensaje en el Bloc de Notas y posteriormente lo pego en la respuesta del mensaje.

    > Como todos los cambios los hago sobre DBO_Articulo no hay actualizacion automatica.

    En teoría así es, porque como estás trabajando con la referencia del objeto del tipo DBO_Articulos pasado al constructor de la clase, todas las modificaciones que se hagan en el mismo se tendrán que ver en el formulario llamador o Maestro. Por tanto, no necesitarías tener una propiedad pública (GetValues) para que te devuelva el objeto modificado. Si fuera un tipo de objeto por valor (un Integer, Long, una estructura) otro gallo cantaría.

    >  Overrides Sub MoveRecord(ByVal Move As String)
    >        Select Case Move
    >            Case Is = "First"
    >                m_Pos = 0
    >            Case Is = "Previous"
    >                m_Pos -= 1
    >            Case Is = "Next"
    >                m_Pos += 1
    >            Case Is = "Last"
    >                m_Pos = GeneralBindingSource.Count - 1
    >        End Select
    >        GeneralBindingSource.Position = m_Pos
    >
    >        DBO_Articulo = spArticulos.Select_Record(GeneralBindingSource(m_Pos).Item("ArticuloID"))
    >
    >        SetValores()
    >    End Sub

    Tal y como remarco en negrita, a la variable DBO_Articulo le estás asignando el valor devuelto por el método Select_Record. ¿No será que éste valor pueda ser distinto a aquel que le has pasado al constructor de la clase?

    Mientras que en el formulario Detalle trabajes con la misma referencia del objeto pasado al constructor, las modificaciones se verán reflejadas en el mismo objeto de la clase Maestro. Pero si en el formulario Detalle modificas el valor de la variable objeto DBO_Articulos para que referencie otro objeto distinto, entonces en el formulario Maestro se verán los datos de la nueva referencia. ¿Me explico?


    >    Public Sub New(ByRef Articulo As DBO_Articulos, ByVal Pos As Integer)
    >        InitializeComponent()
    >        DBO_Articulo = Articulo
    >        m_Pos = Pos
    >    End Sub

    Mejor será que definas el primer parámetro por valor (ByVal), porque repito que estamos trabajando con objetos por referencia, porque el objeto DBO_Articulos será una clase, ¿o es una estructura? Dime si es una clase o una estructura, porque estas últimas son tipos de datos por valor.

     

     


    Enrique Martínez
      [MS MVP - VB]

    domingo, 19 de diciembre de 2010 11:03
    Moderador
  • Es una clase

    Public Class DBO_Articulos

       Private m_ArticuloID As Int32
       Private m_CodigoQS As Int32
       Private m_CodigoQS_IsDBNull As Boolean
       Private m_Descripcion As String
       Private m_Descripcion_IsDBNull As Boolean
       Private m_FechaModificacion As DateTime
       Private m_FechaModificacion_IsDBNull As Boolean
       Private m_UsuarioModificacion As Int32
       Private m_UsuarioModificacion_IsDBNull As Boolean

       Public Sub New()

       End Sub

    .........

     

    como se trata de una edicion no entra en

    Overrides Sub MoveRecord(ByVal Move As String)

     

    Desde el maestro si se ve que han cambiado las propiedades del objeto pasado, lo veo usando el msgbox,

    Using frmEnt As New frmEntArticulos(DBO_Articulo, m_Pos)
                'Dim frmEnt As New frmEntArticulos(DBO_Articulo, m_Pos)
                frmEnt.Text = String.Format("{0} {1}", TipoAction, Titulo)
                frmEnt.ShowDialog()
                DBO_Articulo = frmEnt.GetValues
                'MsgBox(DBO_Articulo.Descripcion.ToString)
                'GeneralBindingSource.ResetCurrentItem()
                'GeneralBindingSource.ResetItem(m_Pos)

            End Using
            'GeneralBindingSource.DataSource = DataTableFill(spSelectDgv)

     

    El problema sigue siendo que no consigo refrescar la grilla.

    he intentado con

     'GeneralBindingSource.ResetCurrentItem()
                'GeneralBindingSource.ResetItem(m_Pos)
                'GeneralBindingSource.ResetBindings(True)
                'dgvGrilla.CurrentRow.SetValues()

    Pero nada.

     

     

     

     

     

     

     


    Miguel Angel Martinez correomam@gmail.com
    domingo, 19 de diciembre de 2010 11:27
  • > Desde el maestro si se ve que han cambiado las propiedades del
    > objeto pasado, lo veo usando el msgbox,
    >

    Entonces el problema ya no es del formulario Detalle, porque éste modifica los valores del objeto pasado a su constructor.

    > El problema sigue siendo que no consigo refrescar la grilla.
    >
    >    Private Sub Action(ByVal TipoAction As String)
    >
    >        Dim DBO_Articulo As New DBO_Articulos
    >        Dim m_Pos As Integer = GeneralBindingSource.Position
    >
    >        If TipoAction = "Insertar" Then
    >            'Asignar las propiedades del objeto creado cuyos valores se obtengan en este Form.
    >        Else
    >            DBO_Articulo = spArticulos.Select_Record(GeneralBindingSource(m_Pos).Item("ArticuloID"))
    >        End If
    >
    >       Using frmEnt As New frmEntArticulos(DBO_Articulo, m_Pos)
    >
    >            frmEnt.Text = String.Format("{0} {1}", TipoAction, Titulo)
    >
    >            frmEnt.ShowDialog()
    >
    >            DBO_Articulo = frmEnt.GetValues
    >
    >        End Using
    >
    >        'GeneralBindingSource.DataSource = DataTableFill(spSelectDgv)
    >
    >    End Sub

    ¿Y tampoco se refresca mediante el método ResetBindings?

        GeneralBindingSource.ResetBindings(True)

    ¡No sé! Entiendo que una vez se cierre el formulario Detalle y llames a dicho método, se debería de refrescar la "grilla". ¿?

    Fijándonos en el código del método Action, creas una nueva instancia por defecto de la clase DBO_Articulos:

         Dim DBO_Articulo As New DBO_Articulos

    la cual es la que se utilizará cuando el TipoAction sea igual a "Insertar". Si el parámetro es distinto a "Insertar", a la variable objeto declarada le estás asignando el valor devuelto por el método Select_Record, el cual devolverá un objeto de acuerdo a los valores de los parámetros pasados. Si ese objeto devuelto es del tipo DBO_Articulos, entiendo que será el objeto que se modificará cuando llames al formulario Detalle.

    De todas maneras, si por "grilla" entendemos un control DataGridView, lo correcto entiendo que es referenciar el objeto DataGridViewRow, que representará la fila seleccionada actualmente en el control, tal y como así aparece en mi artículo, porque tú lo que estás referenciando es un objeto del tipo DBO_Articulos, que obviamente es distinto de un objeto DataGridViewRow, aunque éste contenga los valores del objeto DBO_Articulos. Si tu intención es refrescar la "grilla", tendrás que asignar nuevamente la propiedad DataSource del control BindingSource, siempre y cuando la "grilla" se encuentra enlazada al mencionado control.

    Si deseas hacer una prueba, en lugar de referenciar el objeto que se encuentra en una posición concreta del control BindingSource, referencia la fila actual del control DataGridView, y al formulario Detalle le pasas ese objeto DataGridViewRow. Obviamente, tendrás que incluir una nueva sobrecarga en el contructor del formulario Detalle para que acpete dicho objeto, y trabajar con ese objeto. Como se está trabajando con la lista subyacente enlazada al control BindingSource, los cambios serán automáticos, o al menos eso es lo que dice la teoría. :-)

    Por cierto

    > GeneralBindingSource(m_Pos).Item("ArticuloID")

    Ese control llamado GeneralBindingSource, ¿es alguna clase que has diseñado para que herede de la clase BindingSource?

    Si la respuesta es negativa, ¿tienes activada la preceptiva instrucción Option Strict?

     


    Enrique Martínez
      [MS MVP - VB]

    • Marcado como respuesta mam01 domingo, 19 de diciembre de 2010 19:31
    domingo, 19 de diciembre de 2010 12:24
    Moderador

  • > ¿Y tampoco se refresca mediante el método ResetBindings?

    >  GeneralBindingSource.ResetBindings(True)

    Tampoco lo hace.

    > De todas maneras, si por "grilla" entendemos un control DataGridView

    si lo llamo grilla, creo que asi lo suelen llamar en hispanoamerica

    > GeneralBindingSource(m_Pos).Item("ArticuloID")

    > Ese control llamado GeneralBindingSource, ¿es alguna clase que has diseñado para que herede de la clase BindingSource?

    No es un control que pertenece al Fomulario base del cual heredo el form que estamos tratando.

    > Si la respuesta es negativa, ¿tienes activada la preceptiva instrucción Option Strict?

    No la tengo activada, arrastro viejos defecto de juventud :-)

    ¿Podria tener algo que ver con lo que estamos tratando?

     

     

     

     

     

     

     

     


    Miguel Angel Martinez correomam@gmail.com
    domingo, 19 de diciembre de 2010 19:31
  • > No la tengo activada, arrastro viejos defecto de juventud :-)
    > ¿Podria tener algo que ver con lo que estamos tratando?
    >

    Tiene que ver con la conversión entre tipos de datos. Si la tuvieras activada, la siguiente asignación no se compilaría:

     DBO_Articulo = spArticulos.Select_Record( _
      GeneralBindingSource(m_Pos).Item("ArticuloID"))

    Tendrías que hacer una conversión explícita al tipo DBO_Articulos, mediante el operador DirectCast, CType o TryCast; el que más te guste de ellos. Pero por el mero hecho de hacer la conversión explícita no quiere decir que se vaya a convertir. Se convertirá si el objeto devuelto por la función se puede convertir a un objeto del tipo DBO_Articulos; en caso contrario obtendrás la oportuna excepción en tiempo de ejecución, salvo que la conversión la hayas efectuado con el operador TryCast, que en lugar de devolver una excepción, asigna directamente el valor Nothing a la variable objeto DBO_Articulo.

    De esa manera estás obteniendo un supuesto objeto del tipo DBO_Articulos, que será lo que contiene la propiedad DataSource del objeto GeneralBindingSource. Pero como te indiqué en mi anterior mensaje, las filas del control DataGridView son objetos DataGridViewRow, que aunque tengan los datos de una instancia de la clase DBO_Articulos, son dos objetos completamente diferentes.

    Si quieres que las modificaciones surtan efecto automáticamente, sin necesidad de llamar a métodos de refresco alguno, en el formulario Detalle tendrás que pasarle un objeto DataGridViewRow que represente la fila actual del control DataGridView. Pero si le pasas un objeto DBO_Articulo, tendrás que modificar manualmente los valores de las celdas correspondientes a la fila del control DataGridView oportuna con los valores devueltos por el formulario Detalle.

    > ¿Y tampoco se refresca mediante el método ResetBindings?
    >
    > GeneralBindingSource.ResetBindings(True)
    >
    > Tampoco lo hace.

    Eso ya no me cuadra mucho. Entiendo que sí debería de actualizarle el valor de la propiedad DataSource del control BindingSource, y por consiguiente, los valores que se muestran en el control DataGridView. Ignoro en estos momentos el motivo de que no lo haga. ¿?

     


    Enrique Martínez
      [MS MVP - VB]

    lunes, 20 de diciembre de 2010 16:11
    Moderador