Debido a mi peculiar forma de programar, me han surgido situaciones que me han obligado, como a muchos de vosotros supongo, a realizar moficiaciones en diversas Clases de FW, algunas de ellas al wBrowse, aunque al final optara por crear mis propios Browses. Me dispongo, por si a alguien le interesa, a exponer dos de tantas sugerencias que le van bien al WBrowse de FW. Son más largas de explicar que de comprender y llevar a cabo y constituyen una mejora razonable. Paciencia.
1) bPreChange
Para listados de personal me gusta desplegar un listbox con la ficha (Editable: con GET's) de la persona a su lado, de manera que a cada vez que cambio de línea en el listbox me cambian los datos en los Get's de la ficha correspondiente. Esto entraña varios problemas, el más importante es cuando cambio algún dato y después cambio de ficha pulsando alguna tecla o pinchando sobre otra línea del Listbox, todo ello sin haber guardado las modificaciones. Personalmente me gusta que el programa me pregunte si quiero guardar los datos antes de cambiar de ficha (lo típico "SI", "NO" "CANCELAR"). Se puede hacer si previamente has guardado el RECNO() de la ficha: preguntas si deseas volver y si le das a "CANCELAR" "Buscas" el RECNO(), y recuperas la ficha. Pero genaralmente el listbox parpadea de forma desagradable, el VSCroll se desplaza arriba y abajo y la línea en la que estaba el foco del Listbox cambia de lugar. Un efecto desagradable y poco profesional.
Lo solucioné con el CodeBlock ::bPreChange, más una variable lógica ::lContinue, La mecánica es bien simple:
hay que colocar ::lContinue := .T. al principio de los métodos 'KeyDown', 'LButtonDown' y 'VScroll' para que llegue como .T. a todos los métodos que implican movimiento del listbox. Después, en cada uno de esos métodos; GoUp(), GoDown(), GoTop(), Etc..., hay que hacer lo siguiente:
IF Se Puede Procesar Movimiento
IF bPrechange # NIL
EVAL(bPrechange, ... <VARIABLES A GUSTO DEL PROGRAMADOR> ...)
ENDIF
IF ::lContinue
...
PROCESAR MOVIMIENTO
...
IF bChange # NIL
EVAL(bChange,Self)
ENDIF
...
ENDIF
Ahora, cuando contestes "CANCELAR" con hacer oLbx:lContinue := .F. te quedas en la ficha pués el Listbox no se ha movido. Parece mucho, pero tan sólo supone una quincena de líneas (muchas repetidas) en el PRG (muy pocos minutos).
También sirve para cualquier otra acción que tengamos que realizar antes de cambiar de registro. Por ejemplo: oDBD:Save(), un repintado o refresco de pantalla, una consulta a tablas, pedidos, avisos, recordatorios, etc...
2) ::nMaxCol
La segunda propuesta, para quien haya aguantado el tostón, tiene que ver con la estética del Listbox. Es más accesoria. Se trata de especificar cuál va a ser la última columna visible más a la izquierda del listbox ¿?. Me explico. Normalmente, cuando pulsamos 'flecha derecha' o pinchamos sobre el HSCroll (en la parte derecha), las columnas del listbox se desplazan hacia la izquierda hasta llegar a la última. Amenudo esa ultima columna es la más estrecha y en esas condiciones ocupa todo el listbox (casi todo el listbox está en blanco). Con ::nMaxCol podemos hacer que esto no ocurra. Por ejemplo, supongamos que tengo 10 columnas para listar, pero se ven de tres en tres, me desplazo hacia la derecha hasta que la la octava columna está a la vista y pegada a la izquierda del listbox, aparecen así a la vista las columnas 8, 9 y 10. No necesito desplazarme más, para no perder la estética de pantalla. Si ::nMaxCol vale 8 (nº de la columna más a la izquierda del listbox), ya no se podría desplazar más. Esto me permitiría, además ocultar una posible onceava columna.
Solución:
Colocar ::nMaxCol := NUMERO MAXIMO DE COLUMAS. en los métodos NEW() y REDEFINE().
Por ejemplo en wBrowse ::nMaxCol := Len( GetColSizes() )
Después hay que establecer el rango del HSCroll: 'RANGE 1,::nMaxCol'
Finalmente en el Método GoRight() habrá que añadir, al principio del todo:
IF ::nColAct < ::nMaxCol // Significa que si la columna más a la izquierda no es menor que ::nMaxCol no se procesa GoRight()
...
RESTO DEL METODO TAL CUAL
...
ENDIF
Para aplicar duarante la programación, sencillamente:
REDEFINE oLbx ID .. OF oDlg ... FIELD ...
...
oLbx:nMaxCol := 8
Espero que sirva de algo.
Un saludo.
Sugerencias LISTBOX
Sugerencias LISTBOX
Nos Gusta Programar
-
- Posts: 824
- Joined: Thu Oct 13, 2005 7:39 am
- Location: Germany
Excuse me Stefan but my english is very bad. It's difficult to me to explain it.
they are two sugests for wBrowse or others owner browses.
1) ::bPreChange
Basically is a CodeBlock to be evaluate before any listbox movement (before changing database record). For example if I have a listbox with a personnel editable card next to it, if I make changes in the record and I click into the listbox withgout saving changes, with this codeblock I could ask user if he want to save them: typical "YES","NO","CANCEL" questions. If I click "CANCEL", with ::bPreChange listbox doesn't move and I could stay it.
To perform it, I need ::bPreChange and ::lContinue logical variable. We must place ::lContinue := .T. at top of 'KeyDown', 'LButtonDown' and 'VScroll' methods to enter all listbox movement methods with .T. value. After that, we'll change GoUp(), GoDown(), GoTop(), Etc..., methods in this way:
METHOD ....
IF I can process movement
IF bPrechange # NIL
EVAL(bPrechange, ... <ANY USEFFULL VARIABLES> ...)
ENDIF
IF ::lContinue ...
OLD METHOD CODE
...
IF bChange # NIL
EVAL(bChange,Self)
ENDIF
...
ENDIF
This is useffull for all actions we need to execut before changing the listbox focus row, like: oDBD:Save(), display refresh or repainting, consulting tables, indexes, warning, advertisments, etc...
2) ::nMaxCol
Imagine you want to list 10 columns with a listbox, but only three of them are visibles at time. If you right scorll the listbox you can consecutively see all the columns (three at each time). When you reach the last one, there is the only one displayed, it occupies all the listbox (nearly a blank listbox). However, when the 8, 9 and 10 columns are displayed (at time) you don't need to right scroll the listbaox yet. This woul be the ::nMaxCol := 8 performence (8 means: the most left visible column). With that, you also could hide a posible eleventh column.
To do it:
FIrst: put, in NEW .and. REDEFINE methods: ::nMaxCol := MAX NUMBER OF COLUMNS. in FW wBrowse: ::nMaxCol := Len( GetColSizes() )
Second: define the HSCroll range like this : 'RANGE 1,::nMaxCol'
Third: In GoRight method type:
IF ::nColAct < ::nMaxCol // It means if most left visible column is less than ::nMaxCol then GoRight() it doesn't process.
...
GORIGHT USUAL METHOD
...
ENDIF
I hope you coul understand it
Regards
they are two sugests for wBrowse or others owner browses.
1) ::bPreChange
Basically is a CodeBlock to be evaluate before any listbox movement (before changing database record). For example if I have a listbox with a personnel editable card next to it, if I make changes in the record and I click into the listbox withgout saving changes, with this codeblock I could ask user if he want to save them: typical "YES","NO","CANCEL" questions. If I click "CANCEL", with ::bPreChange listbox doesn't move and I could stay it.
To perform it, I need ::bPreChange and ::lContinue logical variable. We must place ::lContinue := .T. at top of 'KeyDown', 'LButtonDown' and 'VScroll' methods to enter all listbox movement methods with .T. value. After that, we'll change GoUp(), GoDown(), GoTop(), Etc..., methods in this way:
METHOD ....
IF I can process movement
IF bPrechange # NIL
EVAL(bPrechange, ... <ANY USEFFULL VARIABLES> ...)
ENDIF
IF ::lContinue ...
OLD METHOD CODE
...
IF bChange # NIL
EVAL(bChange,Self)
ENDIF
...
ENDIF
This is useffull for all actions we need to execut before changing the listbox focus row, like: oDBD:Save(), display refresh or repainting, consulting tables, indexes, warning, advertisments, etc...
2) ::nMaxCol
Imagine you want to list 10 columns with a listbox, but only three of them are visibles at time. If you right scorll the listbox you can consecutively see all the columns (three at each time). When you reach the last one, there is the only one displayed, it occupies all the listbox (nearly a blank listbox). However, when the 8, 9 and 10 columns are displayed (at time) you don't need to right scroll the listbaox yet. This woul be the ::nMaxCol := 8 performence (8 means: the most left visible column). With that, you also could hide a posible eleventh column.
To do it:
FIrst: put, in NEW .and. REDEFINE methods: ::nMaxCol := MAX NUMBER OF COLUMNS. in FW wBrowse: ::nMaxCol := Len( GetColSizes() )
Second: define the HSCroll range like this : 'RANGE 1,::nMaxCol'
Third: In GoRight method type:
IF ::nColAct < ::nMaxCol // It means if most left visible column is less than ::nMaxCol then GoRight() it doesn't process.
...
GORIGHT USUAL METHOD
...
ENDIF
I hope you coul understand it
Regards
Nos Gusta Programar
- Detlef Hoefner
- Posts: 312
- Joined: Sat Oct 08, 2005 9:12 am
- Location: Germany
- Contact:
Manuramos,
your English is much, much better than the English of Babelfish translation service.
Sometimes, if i want to read some humorous text i give a Spanish message from the forum to babelfish.
Then i make a first translation into English and after again a translation from this English to German.
The result is always very funny and surrealistic .
So, many thanks for your translation work which allows me to understand your posting.
Best regards,
Detlef
your English is much, much better than the English of Babelfish translation service.
Sometimes, if i want to read some humorous text i give a Spanish message from the forum to babelfish.
Then i make a first translation into English and after again a translation from this English to German.
The result is always very funny and surrealistic .
So, many thanks for your translation work which allows me to understand your posting.
Best regards,
Detlef
-
- Posts: 824
- Joined: Thu Oct 13, 2005 7:39 am
- Location: Germany
- James Bott
- Posts: 4654
- Joined: Fri Nov 18, 2005 4:52 pm
- Location: San Diego, California, USA
- Contact:
You are right James. I know it. But WBrowe use ::bSkip in its SetFilter method, then you couldn't use it with filters and/or scopes.
However, if you want to use it, look that ::bSkip is evaluated in the Skip() method, then you should control all the skips mouvements of the browse, because all mouvements methods call ::Skip( x ) one or more times and continue without noticing a posible ::Skip's return value.
:bPreChange .and. ::lContinue would be exclusive to skipper events. I think.
However, if you want to use it, look that ::bSkip is evaluated in the Skip() method, then you should control all the skips mouvements of the browse, because all mouvements methods call ::Skip( x ) one or more times and continue without noticing a posible ::Skip's return value.
:bPreChange .and. ::lContinue would be exclusive to skipper events. I think.
Nos Gusta Programar
- James Bott
- Posts: 4654
- Joined: Fri Nov 18, 2005 4:52 pm
- Location: San Diego, California, USA
- Contact:
Manuramos,
>You are right James. I know it. But WBrowe use ::bSkip in its SetFilter method, then you couldn't use it with filters and/or scopes.
I see. I don't use those, I use ordScope() and dbsetFilter() instead. I don't know if there is some advantage to using the ones in TWBrowse. I think those were originally developed because NTXs didn't have scopes, but now they do.
James
>You are right James. I know it. But WBrowe use ::bSkip in its SetFilter method, then you couldn't use it with filters and/or scopes.
I see. I don't use those, I use ordScope() and dbsetFilter() instead. I don't know if there is some advantage to using the ones in TWBrowse. I think those were originally developed because NTXs didn't have scopes, but now they do.
James