I designed a special grid which displays custom
controls depending on a field-value using
DYNAMICCURRENTCONTROL.
The real thing will also display more complex
controls.
I had trouble with refreshing the grid and only
found a solution with using KEYBOARD commands.
Does anyone know a better solution:
PUBLIC myform
myform = CREATEOBJECT("test")
myform.SHOW()
* 'special' control: container with checkbox
DEFINE CLASS mycontrol1 AS CONTAINER
WIDTH = 100
HEIGHT = 21
BACKSTYLE = 0
BORDERWIDTH = 0
* dummy-property:
CONTROLSOURCE = ""
NAME = "mycontrol1"
ADD OBJECT check1 AS CHECKBOX WITH ;
TOP = 0, ;
LEFT = 0, ;
HEIGHT = 21, ;
WIDTH = 21, ;
BACKSTYLE = 0, ;
CAPTION = "", ;
NAME = "Check1"
ENDDEFINE
* 2. 'special' control:container with editbox
DEFINE CLASS mycontrol2 AS CONTAINER
WIDTH = 100
HEIGHT = 21
BACKSTYLE = 0
BORDERWIDTH = 0
* dummy-property:
CONTROLSOURCE = ""
NAME = "mycontrol2"
ADD OBJECT Edit1 AS EDITBOX WITH ;
TOP = 0, ;
LEFT = 0, ;
HEIGHT = 21, ;
WIDTH = 91, ;
BACKSTYLE = 0, ;
CAPTION = "", ;
NAME = "Edit1"
ENDDEFINE
*normal column
DEFINE CLASS mycolumn1 AS COLUMN
ADD OBJECT text1 AS TEXTBOX WITH ;
BORDERSTYLE = 0,;
NAME = "Text1"
ENDDEFINE
*column with added controls
DEFINE CLASS mycolumn2 AS mycolumn1
* the central property of this example grid:
DYNAMICCURRENTCONTROL =;
"IIF(RECNO('c_test')="+;
"THISFORM.grid1.recordno,"+;
"THISFORM.grid1.alternativecontrol,'Text1')"
ADD OBJECT mycontrol1 AS mycontrol1 WITH ;
NAME = "Mycontrol1"
ADD OBJECT mycontrol2 AS mycontrol2 WITH ;
NAME = "Mycontrol2"
ENDDEFINE
*grid with 2 columns
DEFINE CLASS mygrid AS GRID
COLUMNCOUNT = 0
ROWHEIGHT = 25
DELETEMARK = .F.
HEIGHT = 309
LEFT = 12
PANEL = 1
SCROLLBARS = 2
TOP = 12
WIDTH = 428
recordno = 1
alternativecontrol = "Mycontrol1" && flexible!
gobackto1 = .F.
gobackto2 = .F.
NAME = "Grid1"
ADD OBJECT Column1 AS mycolumn1 WITH;
CONTROLSOURCE = "description",;
WIDTH = 195,;
SPARSE = .F.,;
NAME = "Column1"
ADD OBJECT Column2 AS mycolumn2 WITH;
CONTROLSOURCE = "display_value",;
WIDTH = 195,;
SPARSE = .F.,;
NAME = "Column2"
ENDDEFINE
* testform with grid
DEFINE CLASS test AS FORM
TOP = 0
LEFT = 0
HEIGHT = 337
WIDTH = 453
DOCREATE = .T.
CAPTION = "Form"
NAME = "test"
ADD OBJECT gtid1 AS mygrid WITH;
RECORDSOURCE = "c_test",;
NAME = "grid1"
* testdata
PROCEDURE LOAD
CREATE CURSOR c_test(;
description C(10),;
display_value C(10),;
display_type I,;
value1 L NULL,;
value2 M)
INSERT INTO c_test VALUES;
("Author","Yes",1,.T.,"")
INSERT INTO c_test VALUES;
("Happy","No",1,.F.,"")
INSERT INTO c_test VALUES;
("Comment","it's OK",2,.NULL.,"it's OK")
SELECT c_test
GO TOP
ENDPROC
* Here it get's interesting:
PROCEDURE grid1.AFTERROWCOLCHANGE
LPARAMETERS nColIndex
THIS.recordno = RECNO('c_test')
IF nColIndex=2
DO CASE
CASE c_test.display_type = 1
THIS.alternativecontrol = 'Mycontrol1'
THIS.Column2.mycontrol1.check1.CONTROLSOURCE = "value1"
CASE c_test.display_type = 2
THIS.alternativecontrol = 'Mycontrol2'
THIS.Column2.mycontrol2.edit1.CONTROLSOURCE = "value2"
ENDCASE
ENDIF
**************************************
* This is the part I don't like!!!!! *
**************************************
DO CASE
CASE nColIndex = 1 AND THIS.gobackto2
KEYBOARD '{TAB}'
CASE nColIndex = 2 AND THIS.gobackto1
KEYBOARD '{BACKTAB}'
CASE nColIndex = 1
THIS.gobackto1 = !THIS.gobackto1
IF THIS.gobackto1
KEYBOARD '{TAB}'
ELSE
THISFORM.LOCKSCREEN = .F.
ENDIF
CASE nColIndex = 2
THIS.gobackto2 = !THIS.gobackto2
IF THIS.gobackto2
KEYBOARD '{BACKTAB}'
ELSE
THISFORM.LOCKSCREEN = .F.
ENDIF
ENDCASE
ENDPROC
PROCEDURE grid1.BEFOREROWCOLCHANGE
LPARAMETERS nColIndex
THISFORM.LOCKSCREEN = .T.
IF nColIndex=2
DO CASE
CASE c_test.display_type = 1
REPLACE display_value WITH;
IIF(c_test.value1,"Yes","No") IN "c_test"
CASE c_test.display_type = 2
REPLACE display_value WITH;
LEFT(c_test.value2,10) IN "c_test"
ENDCASE
* THIS.alternativecontrol = 'Text1'
* this would cause other display problems.
ENDIF
ENDPROC
ENDDEFINE
Bye, Olaf.
OD> I had trouble with refreshing the grid and only
OD> found a solution with using KEYBOARD commands.
OD> Does anyone know a better solution:
[Sorry, skipped]
OD> Bye, Olaf.
Untested idea.
Replace
KEYBOARD '{TAB}' with: this.activatecell(this.activerow, 2)
and
KEYBOARD '{BACKTAB}' with: this.activatecell(this.activerow, 1)
Like I said: untested, but it might work for you.
--
Eric den Doop
www.foxite.com - The Home Of The Visual FoxPro Experts - Powered By VFP8
> Untested idea.
>
> Replace
> KEYBOARD '{TAB}' with: this.activatecell(this.activerow, 2)
> and
> KEYBOARD '{BACKTAB}' with: this.activatecell(this.activerow, 1)
Thanks for your try!
Unfortunately activatecell made it slower (sometimes much slower) and
also buggy (wrong control displayed).
I think I can live with KEYBOARD, perhaps in VFP8 It'll work without the
change/changeback active column trick. I could also optimize, that the
Code in BEFOREROWCOLUMNCHANGE is only done, when gobackto2
is .F.
Other suggestions?
Or perhaps an explaination of the gridbehaviour without the
KEYBOARD-Commands?
Bye, Olaf.