Class DataRef() Foundation
Class function of the DataRef class.
The exclusive purpose of objects of the DataRef class is to reference data. Many Xbase Parts are derived from this class and the XbpWindow class. Since it has a visual representation and can access data, an Xbase Part is derived from XbpWindow as well as from DataRef. An Xbase Part can then manage both the screen display and the data.
The DataRef class provides services for other classes and is only significant in relation to other classes. A DataRef object is useless by itself. The service of a DataRef object is to reference data which is stored in variables (field variables or memory variables). This includes reading, assigning values to variables, data validation and the ability to undo changes made to the data.
The most important methods of a DataRef object are :setData() and :getData(). These two methods are used to define the current value in an Xbase Part edit buffer or to read the value and assign it to a variable. In this discussion of the DataRef class, the XbpSLE class is used to illustrate the DataRef class. The edit buffer of the XbpSLE object is set and read using :setData() and :getData(). The XbpSLE class is derived from DataRef and consequently these two methods also exist for XbpSLE objects. This can be shown in the following program code:
cText := "Copy characters into the edit buffer"
oSLE:setData( cText )
// process events within SLE (Event loop)
cText := oSLE:getData()
? cText // result: what the user has input
This program code illustrates the use of the methods :setData() and :getData(). :setData() is used to pass data to the Xbase Part and :getData() is later used to read the data. In the meantime, data is processed by the user within the event loop.
In the example, an argument (the memory variable cText) is passed to the method :setData() and the return value of :getData() is assigned to the variable cText. This process can be automated by assigning a code block for data handling to the instance variable :dataLink:
cText := "Pass characters to the edit buffer"
oSLE:dataLink := {|x| IIf( x==NIL, cText, cText := x) }
oSLE:setData()
// process events within SLE (Event loop)
oSLE:getData()
? cText // result: whatever the user has input
In this modified example, the data is passed between the memory variable and the Xbase Part using the data code block assigned to the instance variable :dataLink. When :dataLink contains a code block, this code block is evaluated by the method :setData() with no arguments. The value of the variable (the return value of the code block) is then sent to the Xbase Part. In the example, the value of cText is copied into the edit buffer of the input field oSLE. When :getData() is called, the current value of the Xbase Part is passed to the code block. The code block contained in :dataLink assigns the value to a variable referenced by the code block.
// This illustrates the basic relationship of :dataLink,
// :validate, :setData(), :getData() and :undo() in an
// example with two input fields (SLE) and two pushbuttons
// (PB). The SLEs allow editing of the two fields and the
// PBs move the record pointer. The UDF WriteSkip() performs
// record locking, validating, writing, skipping and re-reading
// the data.
#include "Xbp.ch"
#include "Appevent.ch"
PROCEDURE Main
LOCAL nEvent:=0 , mp1, mp2, oXbp
LOCAL oSle1, oSle2
FIELD LName, FName
SetColor("N/W")
CLS
USE Customer
// create two SLEs for editing the fields
oSle1 := XbpSle():new( ,, {110,230}, {210,25} )
oSle1:dataLink := {|x| IIf( x==NIL, LName, LName:=x ) }
oSle1:validate := {|o| ! Empty( o:editBuffer() ) }
oSle1:create():setData()
oSle2 := XbpSle():new( ,, {110,170}, {210,25} )
oSle2:dataLink := {|x| IIf( x==NIL, FName, FName:=x ) }
oSle2:validate := {|o| ! Empty( o:editBuffer() ) }
oSle2:create():setData()
// create two pushbuttons for skipping
oXbp := XbpPushButton():new ( ,, {110,80}, {100,30} )
oXbp:caption := "~Next"
oXbp:create()
oXbp:activate := {|| WriteSkip( {oSle1, oSle2}, 1 ) }
oXbp := XbpPushButton():new ( ,, {220,80}, {100,30} )
oXbp:caption := "~Previous"
oXbp:create()
oXbp:activate := {|| WriteSkip( {oSle1, oSle2},-1 ) }
DO WHILE nEvent <> xbeP_Close
nEvent := AppEvent( @mp1, @mp2, @oXbp )
oXbp:handleEvent( nEvent, mp1, mp2 )
ENDDO
RETURN
// write data from the Xbase Parts into the file before
// moving the record pointer
//
PROCEDURE WriteSkip( aXParts, nSkip )
LOCAL i, imax, oXbp
IF DbRLock( Recno() ) // lock data record
imax := Len( aXParts )
FOR i:=1 TO imax
oXbp := aXParts[i]
IF oXbp:validate() // validate data
oXbp:getData() // write data to file
ELSE
oXbp:undo() // validation failed
ENDIF
NEXT
DbRUnlock( Recno() ) // release lock
ENDIF
DbSkip( nSkip ) // move record pointer
FOR i:=1 TO imax
aXParts[i]:setData() // assign fields to XBPs
NEXT
RETURN
If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.