https://foro.gambas-es.org/viewtopic.php?f=4&t=861&p=4839#p4839
-----------------------------------
shordi
Martes, 10 Agosto 2010, 20:01

Mas Sobre GridView Heredado Y Su Evento Data
-----------------------------------
Esto es lo que intento hacer:

Un gridview que contenga en sí mismo todo lo necesario para la visualización de la base de datos, a saber: una conexión, una sentencia sql, un orden, y un Result, de forma que no necesite ser alimentado en cada formulario y que pueda ser manejada como objeto.

Para ello tengo esta nueva clase que llamo, por ejemplo, "migrid"


[code linenumbers=false syntax=gambas]

'' Gambas class file
INHERITS GridView

PUBLIC consulta AS String
PUBLIC orden AS String
PUBLIC clave AS Integer
PUBLIC rsDatos AS Result
PUBLIC hconn AS conexion
PUBLIC hcon AS connection

'En creación recibimos todo lo necesario
PUBLIC PROCEDURE _new(elsql AS String, elorden AS String, lacolclave AS Integer, laconec AS Connection, elcontenedor AS Object)
  ME.consulta = elsql
  ME.orden = elorden
  ME.clave = lacolclave
  ME.hcon = laconec
  ME.width = elcontenedor.width - 50
  ME.Height = elcontenedor.height - 60
  ME.Header = 3
  ME.Resizable = TRUE
  ME.ScrollBar = 3
  ME.visible = TRUE
  refrescar()   'efectuamos la consulta y rellenamos el griview
END

PUBLIC FUNCTION refrescar() AS Boolean

  DIM lret AS Boolean
  DIM oldtag AS NEW Variant[]
  ME.consulta = If(InStr(LCase(ME.consulta), "select"), ME.consulta, "select * from " & ME.consulta)
  ME.consulta = If(ME.orden, ME.consulta & " order by " & ME.orden, ME.consulta)
  TRY ME.rsDatos = ME.hcon.Exec(ME.consulta)   'la forma de conectar es provisional, pero funciona de momento
  IF ERROR THEN
    TRY ME.hcon.Open
    IF ERROR THEN   
      TRY ME.hcon.Close
      TRY ME.hcon.Open
      IF ERROR THEN 
        Message("Imposible conectar con la base de datos")
        RETURN FALSE
      ENDIF 
    ENDIF   
    TRY ME.rsDatos = ME.hcon.Edit(ME.consulta)
    IF ERROR THEN 
        Message("Imposible efectuar la consulta")
        RETURN FALSE
    ENDIF  
  ENDIF   
  lret = ME.formatear() 'Creamos las columnas, los títulos, los anchos, etc.
  RETURN lret
END 

PUBLIC FUNCTION formatear() AS Boolean
  DIM hTable AS Table
  DIM hField AS ResultField
  DIM sField AS String
  DIM iInd AS Integer
  DIM iLen, ileng, n, i AS Integer
  DIM lret AS Boolean
  
  INC Application.Busy
  lret = TRUE
  IF NOT ME.rsDatos THEN
    DEC Application.Busy
    RETURN lret
  ENDIF 
  ME.Rows.Count = 0
  ME.Columns.Count = ME.rsDatos.Fields.Count
  FOR EACH hField IN ME.rsDatos.Fields
    WITH hField
     SUPER.Columns[iInd].Text = .Name
      IF .Type <> 9 THEN 
         iLeng = .Length
      ELSE 
          iLeng = Len(ME.rsDatos[.Name])
          IF ileng > 0 THEN 
            n = (.Length / 3) - ileng
            n = n / 2
             ileng = Int(ileng + n)
          ELSE 
             ileng = .Length
          ENDIF    
      ENDIF   
      TRY SUPER.Columns[iInd].Width = ME.anchoportipo(.Type, iLeng, .Name)
      IF ERROR THEN 
        Message(Error.Text)
      ENDIF 
    END WITH

    INC iInd
  NEXT
' ODBC devuelve mal el total de registros
  IF ME.rsDatos.Count = -1 THEN
    SUPER.Rows.Count = SUPER.rowcount 
  ELSE
    SUPER.Rows.Count = ME.rsDatos.Count
  ENDIF

FINALLY

  DEC Application.Busy
  RETURN lret

CATCH

  Message.Error("Imposible ejectuar la solicitud. Error: " & "\n\n" & DConv(Error.Text))
  lret = FALSE

END
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Este es el evento que nunca se ejecuta y no sé dónde colocar
PUBLIC SUB Data(Row AS Integer, Column AS Integer)
   
        ME.rellenar(Row, Column)
 
END
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

PUBLIC SUB rellenar(Row AS Integer, Column AS Integer)
  'tipico evento data de sincronización entre la tabla y el gridview
  ME.rsDatos.MoveTo(Row)
  ME[row, column].Text = Str(ME.rsDatos[ME.Columns[Column].Text])
  IF (Row MOD 2) == 0 THEN
   ME.Data.Background = Color.White
  ELSE 
   ME.Data.Background = color.RGB(162, 209, 236)
  ENDIF 
  ME.Data.Foreground = Color.black

END

PUBLIC FUNCTION anchoportipo(iType AS Integer, iLength AS Integer, sTitle AS String) AS Integer

  'función pillada por ahí, pendiente de mejoras...
  
  DIM iWidth AS Integer

  SELECT CASE iType

    CASE gb.Boolean
      iWidth = SUPER.Font.Width(Str(FALSE)) + 32

    CASE gb.Integer
'     iWidth = hCtrl.Font.Width("1234567890") + 16
      iWidth = SUPER.Font.Width("123456") + 16
    CASE gb.Long
      iWidth = SUPER.Font.Width("12345678901234567890") + 16
    CASE gb.Float
 '     iWidth = hCtrl.Font.Width(CStr(Pi) & "E+999") + 16
       iWidth = SUPER.Font.Width("12345678") + 16
    CASE gb.Date
      iWidth = SUPER.Font.Width(Str(Now)) + 16
    CASE gb.String
      IF iLength = 0 THEN iLength = 255
      iLength = Min(32, iLength)
      iWidth = SUPER.Font.Width("X") * iLength + 16

  END SELECT

  iWidth = Max(iWidth, SUPER.Font.Width(sTitle) + 8)

  RETURN iWidth

END

PUBLIC FUNCTION rowcount() AS Integer

  DIM rows AS Integer

  rows = 0
  DO
    ME.rsDatos.MoveTo(rows)
    INC rows
  LOOP

CATCH

  RETURN rows

END

PUBLIC SUB ordenar(Column AS Integer)
  ' para el evento column_click del gridview
  DIM old_orden AS String
  DIM n AS Integer
  DIM new_orden AS String
  INC Application.Busy
  old_orden = ME.orden
  new_orden = ME.columns[Column].Title
  n = InStr(new_orden, ".") 
  IF n = 1 THEN 
    new_orden = "`" & Left(new_orden, n - 1) & "`.`" & Right(new_orden, - n) & "`"
  ELSE 
    new_orden = "`" & new_orden & "`"
  ENDIF 
  IF old_orden = new_orden
    new_orden &= " DESC"
  ENDIF 
  ME.orden = new_orden 
  ME.refrescar()
  DEC Application.Busy
  
END

[/code]

Luego creamos un formulario y le asignamos el siguiente código:
[code linenumbers=false syntax=gambas]


PUBLIC elgrid AS migrid
PUBLIC conec AS connection

PUBLIC SUB form_Open()

  'también se podría hacer primero elgrid y luego alimentar las propiedades de la conexion... pero de momento así está 
  conec = NEW connection
  conec.Host = "localhost"
  conec.Type = "mysql"
  conec.Name = "mitabla"
  conec.User = "miusuario"
  conec.Password = "mipassword"

  'parametros: consulta,orden,columna clave,contenedor,creador
  elgrid = NEW migrid("select *from mitabla", "nombre", 1, conec, ME, ME) 'Se repite dos veces el ME, una como contenedor y otra como creador de la clase
                                                                                                            'poco elegante que hay que depurar... cuando funcione, claro.
  
END

PUBLIC SUB elgrid_Data(Row AS Integer, Column AS Integer) 'no funciona. He probado a llamarla Data a secas pero tampoco...

    elgrid.rellenar(Row, Column)

END

PUBLIC SUB elgrid_ColumnClick(Column AS Integer)

    elgrid.ordenar(Column)

END
[/code]

Con esto teóricamente debería crearse el gridview, que se crea, con las columnas, que se crean, y sus datos que NO se crean por falta de evento Data...

¿Alguna idea? Me lleva loco el tema....

Suerte


