xBrowse con "array vacio"

Post Reply
User avatar
Daniel Garcia-Gil
Posts: 2365
Joined: Wed Nov 02, 2005 11:46 pm
Location: Isla de Margarita
Contact:

xBrowse con "array vacio"

Post by Daniel Garcia-Gil »

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

   DATA lHeader,;  // Browse has header, if this value is nil then is initialized automatically on the Adjust method


AGREGAR ANTES

Code: Select all | Expand

   DATA lEmptyArray AS LOGICAL INIT .F.


BUSCAR EN EL METHOD PAINT

Code: Select all | Expand

   /*
   Paint cols data
   */


AGREGAR DESPUES

Code: Select all | Expand

   if ::lEmptyArray .and. ::nDataType == DATATYPE_ARRAY
      ::DispEnd( aInfo )
      return 0
   endif
 


BUSCAR EN EL METHOD KEYDOWN

Code: Select all | Expand

   case nKey == VK_UP


AGREGAR DESPUES

Code: Select all | Expand

     if ::lEmptyArray .and. ::nDataType == DATATYPE_ARRAY
         return 0
      endif


BUSCAR EN EL METHOD KEYDOWN

Code: Select all | Expand

   case nKey == VK_LEFT


AGREGAR DESPUES

Code: Select all | Expand

      if ::lEmptyArray .and. ::nDataType == DATATYPE_ARRAY
         return 0
      endif
 

BUSCAR EN EL METHOD KEYDOWN

Code: Select all | Expand

   case nKey == VK_RIGHT


AGREGAR DESPUES

Code: Select all | Expand

      if ::lEmptyArray .and. ::nDataType == DATATYPE_ARRAY
         return 0
      endif


BUSCAR EN EL METHOD KEYCHAR

Code: Select all | Expand

      otherwise


AGREGAR DESPUES

Code: Select all | Expand

      if ::lEmptyArray .and. ::nDataType == DATATYPE_ARRAY
         return 0
      endif


BUSCAR EN EL METHOD GODOWN

Code: Select all | Expand

   if ::nLen == 0 .or. ::Eof()


AGREGAR AL FINAL DE LA LINEA

Code: Select all | Expand

.or. ( ::lEmptyArray .and. ::nDataType == DATATYPE_ARRAY )


BUSCAR EN EL METHOD LBUTTONDOWN

Code: Select all | Expand

local nOldCol := ::nColSel


AGREGAR DESPUES

Code: Select all | Expand

   if ::lEmptyArray .and. ::nDataType == DATATYPE_ARRAY
      return 0
   endif


BUSCAR EN EL METHOD RBUTTONDOWN

Code: Select all | Expand

local nOldCol := ::nColSel


AGREGAR DESPUES

Code: Select all | Expand

   if ::lEmptyArray .and. ::nDataType == DATATYPE_ARRAY
      return 0
   endif


BUSCAR EN EL METHOD SELECT

Code: Select all | Expand

if ::nMarqueeStyle != MARQSTYLE_HIGHLROWMS


AGREGAR AL FINAL DE LA LINEA

Code: Select all | Expand

.or. ( ::lEmptyArray .and. ::nDataType == DATATYPE_ARRAY )


BUSCAR EN EL METHOD PAINDATA

Code: Select all | Expand

   if ! Empty( cData )


AGREGAR ANTES

Code: Select all | Expand

   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

#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
our best documentation is the source code
Isla de Margarita Venezuela.
danielgarciagil@gmail.com
http://tdolphin.blogspot.com/
https://www.dropbox.com/referrals/NTI5N ... rc=global9
User avatar
jll-fwh
Posts: 408
Joined: Fri Jan 29, 2010 8:14 pm
Location: Meliana - Valencia
Contact:

Re: xBrowse con "array vacio"

Post by jll-fwh »

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
Carles
Posts: 1149
Joined: Fri Feb 10, 2006 2:34 pm
Location: Barcelona
Been thanked: 7 times
Contact:

Re: xBrowse con "array vacio"

Post by Carles »

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

#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
Post Reply