xBrowse con "array vacio"

xBrowse con "array vacio"

Postby Daniel Garcia-Gil » Fri Feb 27, 2009 1:32 am

Saludos

Aqui les dejo otro pequeño aporte para la clase TXBrowse

Nos hemos encontrado con la dificultad de no poder usar arrays vacios con XBrowse, tal comno esta diseñada la clase es logico y normal que no se puedan usar arrays sin data ( aArray := {} ), la explicacion mas imple a esto, es que el xbrowse "NO SABE" que datas va a usar, por ejmeplo la cantidad de columnas.
Al tener un array vacio no hay posibilidad de "armar" correctamente el browse, porque los indices que nos sirven como indicador de columnas, no existen.

Hay formas de evitar ese efecto,
1) validar el array y añadir una fila en caso de estar vacio, pero se nos veria una fila en blanco, esto visualmente es poco atractivo, para evitar eso podemos ocultar el browse ( oBrw:Hide() )...
creo que tambien es poco atractivo, nos quedaria un espacio en blanco

estos cambios que planteo puede que nos den una forma simple de solucionar tal problema...

Empezemos...
ya que no podemos crear el browse con un array vacio, entonces.... ciertamente hay que inicializar un array pero debemos mantener esa fila oculta mientras nosotros queramos La idea es crear una data que nos permita visualizar o no esa(s) linea(s) (array de inicializacion)

este es el ejecutable si quieren probar primero antes de hacer algun cambio...

http://www.sitasoft.com/fivewin/test/testarra.rar

METODOS A CAMBIAR...

Pain() (TXBrowse)
KeyDown() (TXBrowse)
KeyChar() (TXBrowse)
GoDown() (TXBrowse)
LButtonDown() (TXBrowse)
RButtonDown() (TXBrowse)
Select() (TXBrowse)
PainData() (TXBrwColumn)

BUSCAR
Code: Select all  Expand view  RUN
   DATA lHeader,;  // Browse has header, if this value is nil then is initialized automatically on the Adjust method


AGREGAR ANTES
Code: Select all  Expand view  RUN
   DATA lEmptyArray AS LOGICAL INIT .F.


BUSCAR EN EL METHOD PAINT
Code: Select all  Expand view  RUN
   /*
   Paint cols data
   */


AGREGAR DESPUES
Code: Select all  Expand view  RUN
   if ::lEmptyArray .and. ::nDataType == DATATYPE_ARRAY
      ::DispEnd( aInfo )
      return 0
   endif
 


BUSCAR EN EL METHOD KEYDOWN
Code: Select all  Expand view  RUN
   case nKey == VK_UP


AGREGAR DESPUES
Code: Select all  Expand view  RUN
     if ::lEmptyArray .and. ::nDataType == DATATYPE_ARRAY
         return 0
      endif


BUSCAR EN EL METHOD KEYDOWN
Code: Select all  Expand view  RUN
   case nKey == VK_LEFT


AGREGAR DESPUES
Code: Select all  Expand view  RUN
      if ::lEmptyArray .and. ::nDataType == DATATYPE_ARRAY
         return 0
      endif
 

BUSCAR EN EL METHOD KEYDOWN
Code: Select all  Expand view  RUN
   case nKey == VK_RIGHT


AGREGAR DESPUES
Code: Select all  Expand view  RUN
      if ::lEmptyArray .and. ::nDataType == DATATYPE_ARRAY
         return 0
      endif


BUSCAR EN EL METHOD KEYCHAR
Code: Select all  Expand view  RUN
      otherwise


AGREGAR DESPUES
Code: Select all  Expand view  RUN
      if ::lEmptyArray .and. ::nDataType == DATATYPE_ARRAY
         return 0
      endif


BUSCAR EN EL METHOD GODOWN
Code: Select all  Expand view  RUN
   if ::nLen == 0 .or. ::Eof()


AGREGAR AL FINAL DE LA LINEA
Code: Select all  Expand view  RUN
.or. ( ::lEmptyArray .and. ::nDataType == DATATYPE_ARRAY )


BUSCAR EN EL METHOD LBUTTONDOWN
Code: Select all  Expand view  RUN
local nOldCol := ::nColSel


AGREGAR DESPUES
Code: Select all  Expand view  RUN
   if ::lEmptyArray .and. ::nDataType == DATATYPE_ARRAY
      return 0
   endif


BUSCAR EN EL METHOD RBUTTONDOWN

Code: Select all  Expand view  RUN
local nOldCol := ::nColSel


AGREGAR DESPUES
Code: Select all  Expand view  RUN
   if ::lEmptyArray .and. ::nDataType == DATATYPE_ARRAY
      return 0
   endif


BUSCAR EN EL METHOD SELECT
Code: Select all  Expand view  RUN
if ::nMarqueeStyle != MARQSTYLE_HIGHLROWMS


AGREGAR AL FINAL DE LA LINEA
Code: Select all  Expand view  RUN
.or. ( ::lEmptyArray .and. ::nDataType == DATATYPE_ARRAY )


BUSCAR EN EL METHOD PAINDATA
Code: Select all  Expand view  RUN
   if ! Empty( cData )


AGREGAR ANTES
Code: Select all  Expand view  RUN
   if ::oBrw:lEmptyArray .and. ::oBrw:nDataType == DATATYPE_ARRAY
      return nil
   endif
 


les dejo un ejemplo de facil comprencion, se puede hacer uso de esa data (lEmptyArray) y ocultar o mostar las
filas del browse

Code: Select all  Expand view  RUN
#include "fivewin.ch"
#include "xbrowse.ch"

function TestMain()

   local oWnd
   local oBrw
   local oBar
   local lEmpty := .f.
   
   local aArray := {}
   
   DEFINE WINDOW oWnd TITLE "Testing Empty Array xBrowse"
   
   DEFINE buttonbar oBar of oWnd
   
   define button of oBar action ( oBrw:lEmptyArray := .f., oBrw:Refresh() )
   define button of oBar action ( oBrw:lEmptyArray := .t., oBrw:Refresh() )
   define button of oBar action ( oWnd:end() )
 
   if empty( aArray )                          
      aArray := {{"   ","   ","   ","   "}}    
      lEmpty := .t.
   endif
   


   
   @ 0,0 XBROWSE oBrw OF oWnd ;
      COLUMNS {1,2,3,4} ;
      HEADERS {"uno","dos","tres","cuatro"} ;
      array aArray LINES CELL fastedit

   oBrw:lEmptyArray := lEmpty
   
   oBrw:bPastEof := {|| if ( oBrw:lEmptyArray, ;
                            oBrw:lEmptyArray:= .f., ;
                            ( aadd( oBrw:aArrayData,{"   ","   ","   ","   "} ), oBrw:GoDown()) ),;
                            oBrw:Refresh() }
   
   oBrw:bKeyDown := {| nKey | EraseRow( oBrw, nKey ) }
   
   aeval( oBrw:aCols, { |oCols| oCols:nEditType := EDIT_GET } )
   
   oWnd:oClient := oBrw
   
   oBrw:createfromcode()
   
   activate window oWnd
   
return nil

procedure EraseRow( oBrw, nKey )

   if nKey == VK_DELETE .and. !oBrw:lEmptyArray
   
   #ifdef __XHARBOUR__
            aDel( oBrw:aArraydata, oBrw:nArrayAt,.t. )
     #else
            aDel( oBrw:aArraydata, oBrw:nArrayAt )
            ASize( oBrw:aArraydata, len( oBrw:aArraydata ) - 1 )
     #endif
        if empty( oBrw:aArraydata )
           oBrw:aArraydata := {{"   ","   ","   ","   "}}
           oBrw:lEmptyArray := .t.
        endif
     endif
     oBrw:refresh()
return
User avatar
Daniel Garcia-Gil
 
Posts: 2365
Joined: Wed Nov 02, 2005 11:46 pm
Location: Isla de Margarita

Re: xBrowse con "array vacio"

Postby jll-fwh » Wed Nov 17, 2010 12:32 am

Hola Daniel:

Acabo de leer este hilo sobre los xBrowse con Array, la fecha de este hilo es de febrero del 2009, y yo uso una version del 2008, que le pasa lo mismo, aunque yo lo uso sin realizar ninguna modificacion de la clase y me funciona correctamente, yo lo hago asi, y en xBrowse con array sin nigun elemento me sale vacio, aunque tiene truco.

Comento:

Inicializo el Array con los elementos, de este modo tambien me sirve para identificar en el codigo que es cada elemento del array, ejemplo es el programa de pruebo que eso:

aTSegui := { { 1 ,; // Bitmap
Date(),; // Fecha
Time(),; // Hora
0.00 ,; // Peso
0.00 ,; // Humedad
0.00 }} // Temperatura

Declaro el xBrowse con array como siempre:

REDEFINE XBROWSE oGridS ARRAY aTSegui ID 200 OF oDlg FONT oFont

oGridS:SetArray( aTSegui )
oGridS:l2007 := .F.
.......

El truco esta en la llamada a la funcion que carga los datos en ON INIT es este:

Si hemos cargado informacion en el Array, nada, se deja, y si no hemos seleccionado ningun registro a cargar, simplemente hay que vaciar el array con aSize para que borre el elemento que tenemos pendiente al inicializar el array, antes de cargar los nuevos datos. de este modo cuando se crea el control tiene los datos que necesita, pero cuando nosotros cargamos la informacion, antes lo vaciamos.

aSize( aTSegui, 0 )

Solo lo comento por si algun compañero no quiero modifcar la clase, hay una forma de poder trabajar sin modificaciones.

Si alguien lo necesita, puedo aportar el codigo entero de un modulo.

Un saludo
JLL
Libreria: FWH/FWH1109 + Harbour 5.8.2 + Borland C++ 5.8.2
Editor de Recursos: PellecC
ADA, OURXDBU
S.O: XP / Win 7 /Win10
Blog: http://javierlloris.blogspot.com.es/
e-mail: javierllorisprogramador@gmail.com
User avatar
jll-fwh
 
Posts: 408
Joined: Fri Jan 29, 2010 8:14 pm
Location: Meliana - Valencia

Re: xBrowse con "array vacio"

Postby Carles » Wed Nov 17, 2010 6:58 am

Hola,

Yo os propongo otra técnica que uso desde hace tiempo y funciona perfectamente con el uso de TXBrowse y Array.

1.- Es en la definicion de controles, cuando debemos crear el Xbrowse y sus columnas con titulos, pictures, alineamiento, ... pero sin el tratamiento de datos.

2.- En el ::Init() del dialogo, ya se habra declarado el xBrowse y es alli donde tenemos de declarar el comportamiento con los datos, datos a leer, a salvar, ...

Code: Select all  Expand view  RUN
#include "FiveWin.Ch"
#include "XBrowse.Ch"

#define ID_STRING    1
#define ID_NUM       2

STATIC oWnd

*--------------
FUNCTION Main()
*--------------

   SetGetColorFocus()

   DEFINE WINDOW oWnd MDI TITLE "Test Xbrowse - Empty Array"
   ACTIVATE WINDOW oWnd ON INIT Test()

RETU NIL

*--------------
FUNCTION Test()
*--------------
   LOCAL oChild, oBrw, oCol, oBar

   DEFINE WINDOW oChild MDICHILD OF oWnd

      DEFINE BUTTONBAR oBar SIZE 23, 26 _3D OF oChild

      DEFINE BUTTON    OF oBar  ACTION BrwRefresh( oBrw,  { Time(), HB_Random(1,99) } ) ;
                                TOOLTIP 'Add Reg'

      DEFINE BUTTON    OF oBar  ACTION BrwRefresh( oBrw ) ;
                                TOOLTIP 'Del All'

   @ 0,0 XBROWSE oBrw ARRAY {} OF oChild LINES CELL

     ADD oCol TO oBrw HEADER "STRING" SIZE 100
     ADD oCol TO oBrw HEADER "NUM"    SIZE  50 ALIGN CENTER

     oBrw:CreateFromCode()

     oChild:oClient := oBrw

   ACTIVATE WINDOW oChild ON INIT InitBrw( oBrw )

RETU NIL


*------------------------------
STATIC FUNCTION InitBrw( oBrw )
*------------------------------
    LOCAL oCol

    oCol := oBrw:oCol( 'STRING')

       oCol:bStrData    := {|| oBrw:aRow[ ID_STRING  ] }
       oCol:nEditType   := EDIT_GET
       oCol:bOnPostedit := {|o, v| oBrw:aRow[ ID_STRING ] := v }

    oCol := oBrw:oCol( 'NUM')

       oCol:bStrData     := {|| oBrw:aRow[ ID_NUM ] }
       oCol:nEditType    := EDIT_GET
       oCol:bOnPostedit  := {|o, v| oBrw:aRow[ ID_NUM ] := v }
       oCol:cEditPicture := '99'

RETU NIL

*---------------------------------------
STATIC FUNCTION BrwRefresh( oBrw, aReg )
*---------------------------------------

    IF aReg == NIL

       oBrw:aArrayData := {}

      ELSE

       Aadd( oBrw:aArrayData, aReg )

    ENDIF

    oBrw:Refresh()

RETU NIL


Y listos...
Salutacions, saludos, regards

"...programar es fácil, hacer programas es difícil..."

UT Page -> https://carles9000.github.io/
Forum UT -> https://discord.gg/bq8a9yGMWh
Skype -> https://join.skype.com/cnzQg3Kr1dnk
User avatar
Carles
 
Posts: 1137
Joined: Fri Feb 10, 2006 2:34 pm
Location: Barcelona


Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: Google [Bot] and 46 guests