El problema que describes ocurre porque AddBitmap() se eval煤a una sola vez cuando se crea la columna, no din谩micamente para cada fila.<cite></cite> Est谩s intentando usar iif(oRSP:Fields("Anulada"):Value = "D", "Devoluci贸n", "N.Pedido") en el momento de la creaci贸n de la columna, lo cual solo lee el valor del primer registro.<cite></cite>
Soluci贸n
Para que el texto del bot贸n cambie din谩micamente seg煤n cada fila, debes usar bStrData en lugar de AddBitmap() est谩tico:<cite></cite>
with object oBrw
oCol := oBrw:AddCol()
oCol:nBtnBmp := 1
oCol:nWidth := 100
oCol:bStrData := { || iif(oRSP:Fields("Anulada"):Value = "D", "Devoluci贸n", "N.Pedido") }
oCol:nEditType := EDIT_BUTTON
oCol:bEditBlock := { | nRow, nCol, oCol, nKey | ;
iif(BuscoPresuControl(oRSp:Fields("presupu"):value,"F"), ;
(lvalorizada := .t., sologra := .t., ;
grabarnp(iif(oRSP:Fields("Anulada"):Value = "D", .t., .f.), .t.), ;
ActualizoPresu()), ) }
end
El bloque bStrData se eval煤a para cada fila cuando se pinta el browse, permitiendo que el texto cambie seg煤n el valor del campo "Anulada" en cada registro. 0-cite-0
Alternativa con TxtToBmp
Si necesitas mantener TxtToBmp() para generar bitmaps din谩micos, usa bBmpData con un array de bitmaps:<cite></cite>
oCol:AddBitmap(TxtToBmp("Verdana", 12, "Devoluci贸n")) // bitmap 1
oCol:AddBitmap(TxtToBmp("Verdana", 12, "N.Pedido")) // bitmap 2
oCol:bBmpData := { || iif(oRSP:Fields("Anulada"):Value = "D", 1, 2) }
oCol:nEditType := EDIT_BUTTON
Esto devuelve el 铆ndice del bitmap (1 o 2) seg煤n el valor del campo. 0-cite-1
Notas
- bStrData es el bloque est谩ndar para mostrar texto din谩mico en celdas de TXBrowse 0-cite-2
- bBmpData devuelve el 铆ndice del bitmap a mostrar cuando usas m煤ltiples bitmaps con AddBitmap() 0-cite-3
- Ambos bloques se eval煤an para cada fila durante el pintado del browse, a diferencia de AddBitmap() que solo se ejecuta una vez<cite></cite>
Wiki pages you might want to explore:
Citations
File: samples/graphics/xbimg.prg (L32-32)
oBrw:aCols[ 1 ]:bStrImage := {|oCol, oBrw| oBrw:aRow[ 2 ] }
File: samples/ui/xbrowse/testxbrw.prg (L425-426)
oCol:bBmpData := { || iif( _FIELD->Married, 1, 2) }
oCol:bStrData := { || iif( _FIELD->Married, "Yes", "No ")}
File: docs/reference/classes/TXBrowse.md (L1-150)
# Clase `TXBrowse`
**Archivo Fuente:** [source/classes/xbrowse.prg](..\source\classes\xbrowse.prg)
## 1. Prop贸sito y Alcance
`TXBrowse` es un control de visualizaci贸n de datos en formato tabular (cuadr铆cula o grilla) extremadamente potente y configurable. Es uno de los componentes m谩s complejos y centrales del framework, dise帽ado para presentar y manipular grandes conjuntos de datos de diversas fuentes.
Sus capacidades principales incluyen:
* **Virtualizaci贸n de Datos:** Est谩 dise帽ado para manejar millones de registros sin consumir memoria, ya que solo renderiza las filas y columnas visibles.
* **Abstracci贸n de Fuente de Datos:** Puede conectarse a pr谩cticamente cualquier fuente de datos (tablas DBF, arrays en memoria, recordsets ADO, consultas SQL) a trav茅s de un conjunto de bloques de c贸digo de navegaci贸n.
* **Columnas Configurables:** Las columnas son objetos (`TXBrwColumn`) que se pueden personalizar extensamente (formato, colores, edici贸n, etc.).
* **Edici贸n en Celda:** Permite la edici贸n directa de los datos en la grilla.
* **Alta Personalizaci贸n Visual:** Ofrece un control granular sobre casi todos los aspectos visuales: colores, l铆neas, cabeceras, pies de p谩gina, etc.
* **Funcionalidades Avanzadas:** Soporta ordenamiento por columna, b煤squeda incremental, selecci贸n m煤ltiple, exportaci贸n de datos (Excel, CSV, etc.) y mucho m谩s.
## 2. Arquitectura y Conceptos Clave
`TXBrowse` hereda de `TControl`, pero su complejidad reside en su arquitectura interna, que se basa en tres pilares:
1. **El Navegador (`TXBrowse`):** Es el objeto principal que gestiona la ventana, las barras de scroll, los eventos de teclado y rat贸n, y orquesta el pintado general.
2. **Las Columnas (`TXBrwColumn`):** La propiedad `aCols` contiene un array de objetos columna. Cada columna define qu茅 dato mostrar y c贸mo mostrarlo. La documentaci贸n de `TXBrwColumn` es esencial para entender `TXBrowse`.
3. **La Fuente de Datos (Abstracci贸n):** `TXBrowse` no conoce los detalles de la fuente de datos. Se comunica con ella a trav茅s de un conjunto de bloques de c贸digo (`bGoTop`, `bGoBottom`, `bSkip`, `bKeyCount`, `bBookMark`). M茅todos como `SetRDD()` o `SetArray()` simplemente configuran estos bloques de c贸digo con la l贸gica apropiada para cada tipo de fuente.
### Diagrama Conceptual
```mermaid
graph TD;
subgraph "Fuente de Datos"
direction LR
DBF;
Array;
ADO;
end
subgraph "TXBrowse"
direction LR
A[Navegador<br>(TXBrowse)] -- contiene --> B(Columnas<br>[TXBrwColumn]);
end
DBF -- "configura" --> C{Bloques de Navegaci贸n<br>bGoTop, bSkip, ...};
Array -- "configura" --> C;
ADO -- "configura" --> C;
C -- "es usado por" --> A;
style A fill:#f9f,stroke:#333,stroke-width:2px;
3. Propiedades y Bloques de C贸digo Clave
Debido a la gran cantidad de propiedades, esta secci贸n se centra en las m谩s importantes para la configuraci贸n inicial.
Propiedades de Configuraci贸n
| Propiedad | Tipo | Descripci贸n |
|-------------------|-----------|---------------------------------------------------------------------------------------------------------|
| aCols | ARRAY | Array de objetos TXBrwColumn que definen las columnas de la grilla. |
| nFreeze | NUMERIC | N煤mero de columnas a la izquierda que permanecer谩n fijas (congeladas) durante el scroll horizontal. |
| lRecordSelector | LOGICAL | Si es .T., muestra una columna a la izquierda para indicar la fila actual. |
| nMarqueeStyle | NUMERIC | Define el estilo de la celda/fila seleccionada (punteado, s贸lido, fila resaltada, etc.). Ver xbrowse.ch. |
| lFastEdit | LOGICAL | Si es .T., permite entrar en modo de edici贸n simplemente escribiendo en una celda editable. |
| lMultiSelect | LOGICAL | Habilita la selecci贸n de m煤ltiples filas. |
Bloques de Navegaci贸n (Data Source)
| Bloque | Par谩metros | Descripci贸n |
|-------------|-------------------|---------------------------------------------------------------------------------------------------------|
| bGoTop | () | Debe posicionar la fuente de datos en el primer registro. |
| bGoBottom | () | Debe posicionar la fuente de datos en el 煤ltimo registro. |
| bSkip | (nToSkip) | Debe mover el puntero nToSkip registros (positivo o negativo). Devuelve el n煤mero de registros realmente movidos. |
| bKeyCount | () | Debe devolver el n煤mero total de registros en la fuente de datos. |
| bBookMark | (uValue) | Si uValue es NIL, devuelve un identificador 煤nico de la fila actual. Si no, va a la fila identificada por uValue. |
| bEof | () | Devuelve .T. si el puntero est谩 despu茅s del 煤ltimo registro. |
| bBof | () | Devuelve .T. si el puntero est谩 antes del primer registro. |
4. M茅todos Clave
| M茅todo | Descripci贸n |
|-------------------------|----------------------------------------------------------------------------------------------------------------------------------------|
| New(oWnd) | (CONSTRUCTOR) Crea una instancia de TXBrowse asociada a una ventana padre. |
| AddColumn(...) | A帽ade y configura una nueva columna (TXBrwColumn) a la grilla. Es un m茅todo m谩s amigable que crear el objeto TXBrwColumn manualmente. |
| SetRDD() | Configura autom谩ticamente los bloques de navegaci贸n para trabajar con el 谩rea de trabajo DBF actual. |
| SetArray(aData) | Configura los bloques de navegaci贸n para trabajar con un array de datos en memoria. |
| SetAdo(oRs) | Configura los bloques de navegaci贸n para trabajar con un RecordSet de ADO. |
| CreateFromCode() | Crea el control visual en la ventana padre despu茅s de haberlo configurado. |
| Adjust() | Calcula las dimensiones de cabeceras, pies y filas. Se llama autom谩ticamente, pero a veces es necesario invocarlo manualmente. |
| Refresh() | Redibuja completamente el contenido de la grilla. |
| SelectedCol() | Devuelve el objeto TXBrwColumn de la columna actualmente seleccionada. |
5. Patrones de Uso y Ejemplos
Ejemplo 1: Browse simple para una tabla DBF
#include "FiveWin.ch"
#include "XBrowse.ch"
FUNCTION Main()
LOCAL oWnd, oBrw
USE Customer VIA "DBFCDX" // Abrir una tabla de ejemplo
DEFINE WINDOW oWnd TITLE "TXBrowse con DBF"
// 1. Crear el objeto TXBrowse
oBrw := TXBrowse():New( oWnd )
oBrw:nTop := 10
oBrw:nLeft := 10
oBrw:nRight := oWnd:nWidth - 10
oBrw:nBottom := oWnd:nHeight - 10
// 2. Configurar la fuente de datos (autom谩tico para el alias actual)
oBrw:SetRDD()
// 3. A帽adir columnas
oBrw:AddColumn( "ID", FieldBlock("CUST_ID"), "99999", , , "R" )
oBrw:AddColumn( "Nombre", FieldBlock("FIRSTNAME"), "@!", , , , , .T. ) // Editable
oBrw:AddColumn( "Apellido", FieldBlock("LASTNAME"), "@!" )
// 4. Crear el control visual
oBrw:CreateFromCode()
ACTIVATE WINDOW oWnd
CLOSE Customer
RETURN NIL
Ejemplo 2: Browse para un Array en memoria
#include "FiveWin.ch"
#include "XBrowse.ch"
FUNCTION Main()
LOCAL oWnd, oBrw
LOCAL aData := { { "Juan", "P茅rez", 30 }, { "Ana", "Garc铆a", 25 }, { "Luis", "Mart铆nez", 42 } }
DEFINE WINDOW oWnd TITLE "TXBrowse con Array"
// 1. Crear el objeto TXBrowse
oBrw := TXBrowse():New( oWnd )
oBrw:nTop := 10, oBrw:nLeft := 10, oBrw:nRight := 400, oBrw:nBottom := 300
// 2. Configurar la fuente de datos
oBrw:SetArray( aData )
// 3. A帽adir columnas, usando bloques de c贸digo para acceder a los elementos del array
File: samples/misc/inspect.prg (L121-122)
:bBmpData = { |v| If( HB_ISLOGICAL(v), If( v, 1, 2 ), 0 ) }
:bStrData = { |x,o| If( HB_ISLOGICAL( x := o:Value ), If( x, "Visible", "Hidden" ) , x ) }