Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Display Info in Tool Tips in a Grid 1

Status
Not open for further replies.

Imaginecorp

IS-IT--Management
Jan 7, 2007
635
US
There is a little bit of cheating here, but without a lot of convoluted code, this is how you do it. The code is amazingly simple.

As the grid displays records in a table, there is no way of knowing what a record contains unless you go to it. That is what this example does by moving the mouse through the rows and columns: Please feel free to fine tune;

Code:
PUBLIC oform1
oform1=NEWOBJECT("form1")
oform1.Show
RETURN


	**************************************************
*-- Form:         form1 (c:\imaginecorp\form11.scx)
*-- ParentClass:  form
*-- BaseClass:    form
*-- Time Stamp:   04/29/07 01:27:09 PM
*
DEFINE CLASS form1 AS form


	Top = 0
	Left = 0
	Height = 269
	Width = 495
	DoCreate = .T.
	ShowTips = .T.
	Caption = "Display information in Tool Tip..."
	Name = "Form1"


	ADD OBJECT grid1 AS grid WITH ;
		ColumnCount = 3, ;
		DeleteMark = .F., ;
		Height = 250, ;
		Left = 8, ;
		Panel = 1, ;
		RecordSource = "customers", ;
		ScrollBars = 2, ;
		Top = 7, ;
		Width = 480, ;
		Name = "Grid1", ;
		Column1.ControlSource = "Customers.customerid", ;
		Column1.Width = 86, ;
		Column1.Name = "Column1", ;
		Column2.ControlSource = "Customers.companyname", ;
		Column2.Width = 193, ;
		Column2.Name = "Column2", ;
		Column3.ControlSource = "Customers.contactname", ;
		Column3.Width = 166, ;
		Column3.Name = "Column3"


	ADD OBJECT form1.grid1.column1.header1 AS header WITH ;
		Caption = "Customer ID", ;
		Name = "Header1"


	ADD OBJECT form1.grid1.column1.text1 AS textbox WITH ;
		BorderStyle = 0, ;
		Margin = 0, ;
		ForeColor = RGB(0,0,0), ;
		BackColor = RGB(255,255,255), ;
		Name = "Text1"


	ADD OBJECT form1.grid1.column2.header1 AS header WITH ;
		Caption = "Company Name", ;
		Name = "Header1"


	ADD OBJECT form1.grid1.column2.text1 AS textbox WITH ;
		BorderStyle = 0, ;
		Margin = 0, ;
		ForeColor = RGB(0,0,0), ;
		BackColor = RGB(255,255,255), ;
		Name = "Text1"


	ADD OBJECT form1.grid1.column3.header1 AS header WITH ;
		Caption = "Contact", ;
		Name = "Header1"


	ADD OBJECT form1.grid1.column3.text1 AS textbox WITH ;
		BorderStyle = 0, ;
		Margin = 0, ;
		ForeColor = RGB(0,0,0), ;
		BackColor = RGB(255,255,255), ;
		Name = "Text1"


	PROCEDURE gridshowinfo
		Lparameters pY,pX,pColumn
		Store 0 To nWhere_Out ,nRelRow_Out, nRelCol_Out, nView_Out
		With This.grid1
			.GridHitTest(pX,pY,@nWhere_Out)
			If nWhere_Out = 3
				nr = Ceiling(Round((pY - (Objtoclient(This.grid1,1)+;
					.HeaderHeight))/.RowHeight,0))
				.ActivateCell(nr,pColumn)
				cAddress = Alltrim(Nvl(customers.address,""))+Chr(13)+;
					ALLTRIM(Nvl(customers.city,""))+Chr(13)+;
					NVL(customers.postalcode,"")+". "+Alltrim(Nvl(customers.country,""))
				cTitle = Alltrim(Nvl(customers.contacttitle,""))+Chr(13)+;
					"Phone: "+Nvl(customers.phone,"")+Chr(13)+;
					"Fax: "+Nvl(customers.Fax,"")
				.ToolTipText = Icase(pColumn = 2,cAddress,;
					pColumn = 3,cTitle,"")
			Else
				.ToolTipText = ""
			Endif
		Endwith
	ENDPROC


	PROCEDURE Load
		If Select("customers") > 0
			Select customers
		Else
			Select 0
			Use Home()+"\samples\northwind\customers.dbf" Shared
		Endif
	ENDPROC


	PROCEDURE grid1.Column1.MouseMove
		LPARAMETERS nButton, nShift, nXCoord, nYCoord
		thisform.gridshowinfo(nYCoord,nXCoord,1)
	ENDPROC


	PROCEDURE grid1.Column2.MouseMove
		LPARAMETERS nButton, nShift, nXCoord, nYCoord
		thisform.gridshowinfo(nYCoord,nXCoord,2)
	ENDPROC


	PROCEDURE grid1.Column3.MouseMove
		LPARAMETERS nButton, nShift, nXCoord, nYCoord
		thisform.gridshowinfo(nYCoord,nXCoord,3)
	ENDPROC


ENDDEFINE
*
*-- EndDefine: form1
**************************************************
 
Thanks, I'm going to try this idea for my application as well.
 
Working on the generic implementation for my grid class right now. Thanks a lot again.
 
It works, but somehow not 100% reliable. E.g. sometimes I see the tooltip and sometimes I don't.

Here is the code in the Init method of the grid:
Code:
FOR EACH loColumn IN THIS.COLUMNS
	loColumn.ADDPROPERTY("cOriginalControlSource", m.loColumn.CONTROLSOURCE)
	BINDEVENT(m.loColumn,"MouseMove",THIS,"ColumnMouseMove")

And this is ColumnMouseMove method - do you see a problem?

Code:
LPARAMETERS nButton, nShift, nXCoord, nYCoord
local loCalledBy as Object, nWhere_Out, nRelRow_Out, ;
nRelCol_Out, nView_Out, nr, lnColumn, lcValue

aevents[aCurEvent,0]
loCalledBy = aCurEvent[1] && should be a column object

if vartype(m.loCalledBy)= "O" and not empty(m.loCalledBy.ControlSource)
	lnColumn = m.loCalledBy.ColumnOrder
    Store 0 To nWhere_Out, nRelRow_Out, nRelCol_Out, nView_Out
        With This
            .GridHitTest(m.nXCoord,m.nYCoord,@nWhere_Out)
            If m.nWhere_Out = 3
                nr = Ceiling(Round((m.nYCoord - (Objtoclient(This,1)+;
                    .HeaderHeight))/.RowHeight,0))                
                .ActivateCell(m.nr,m.lnColumn)
                lcValue = TRANSFORM(EVALUATE(m.loCalledBy.ControlSource))
                IF LEN(m.lcValue) > 40
                	.ToolTipText = m.lcValue
                ELSE
                     .ToolTipText = ""	
                endif                
            Else
                .ToolTipText = ""
            Endif
        Endwith
ENDIF

BTW, whom should I attribute the code - should I just use your nickname?
 
Hello Ilyad;

Excellent! Really like the use of Bindevent(), now you don’t have to call the procedure from every column.

What is Tooltips displaying though? The control source value is already displayed in the Grid. ; IMO the purpose should be to display info that is not part of the grid, you could even do an indexseek or set relationship to another table and display its information. The possibilities are endless. Though do not overload the Mouse Move.

"...E.g. sometimes I see the tooltip and sometimes I don't." quick test of your code shows the Activatecell() to be 3 rows above the mouse pointer. Will test your code later and post back. Kinda burnt out right now and the brain has slowed down… Need a stiff drink...

A quick fix:
Code:
**** Grid INIT()
For Each loColumn In This.Columns
	Bindevent(m.loColumn,"MouseMove",Thisform,"gridshowinfo")
Endfor

**** form gridshowinfo()
Lparameters nButton, nShift, nXCoord, nYCoord
Local loCalledBy As Object, nWhere_Out, nRelRow_Out, ;
	nRelCol_Out, nView_Out, nr, lnColumn, lcValue

Aevents[aCurEvent,0]
loCalledBy = aCurEvent[1] && should be a column object
lnColumn = m.loCalledBy.ColumnOrder

Store 0 To nWhere_Out ,nRelRow_Out, nRelCol_Out, nView_Out
With This.grid1
	.GridHitTest(nXCoord,nYCoord,@nWhere_Out)
	If nWhere_Out = 3
		nr = Ceiling(Round((nYCoord - (Objtoclient(This.grid1,1)+;
			.HeaderHeight))/.RowHeight,0))
		.ActivateCell(nr,lnColumn)
		lcValue = Transform(Evaluate(m.loCalledBy.ControlSource))
		.ToolTipText = lcValue
	Else
		.ToolTipText = ""
	Endif
Endwith

With all due respect, if I may, Keep it simple… Advice I live by and have hammered into my people.{s}

You don’t need to attribute the code to me or anybody else; you took an idea and perfected it... Good Job

 
What was the change you made? I'll play a bit more tomorrow with the code, thank you again.
 
Did not make any changes, just rearanged stuff, Your code should work perfect
 
It doesn't seem to work 100% I may try to combine your ideas with Vlad G ideas from the FAQ. I was also thinking may be we can bound textbox mousemove rather than column's mousemove. Would then it work without activatecell?

I'm going to play a bit with it today. Yesterday, BTW, I already moved that solution into the production, but haven't heard anything from the users (if they notice it at all <g>)

Thank you again.
 
Thank you... will work on it myself tonight...
 
As promised, here Is the Code For a Grid Class:
In the Grid Class:
First: Create a Property, Call it EnableShowInfo
This will Control If the Grid Is To Display Information Or Not.
Default Value Is .F. Change To .T. When Grid Is placed On a Form

Next Create 2 methods, Call Them:
1. GridShowInfo: This holds the Code
2. Tooltip_Info: This has 2 Parameters: pWhichColumn And poColumn.
*!* pWhichColumn = Column Number
*!* pOcolumn = Column Object
This Is Where you place the Information, once the Grid Is On a Form,
that Is To be displayed. This enables you To Display seperate Info For Each Column

Code:
*!*	Grid Init()
If This.EnableShowInfo
	For Each oColumn In This.Columns
		Bindevent(oColumn,"MouseMove",This,"gridshowinfo")
	Endfor
Endif
*!*	Grid GridShowInfo()
Lparameters nButton, nShift, nXCoord, nYCoord
Store 0 To nWhere_Out ,nRelRow_Out, nRelCol_Out, nView_Out

Aevents[aEventArray,0]  &&& 3 Element Array
oColumn = aEventArray[1] &&& Event Source i.e. Column Object
oColumnNumber = oColumn.ColumnOrder

With This
	.GridHitTest(nXCoord, nYCoord,@nWhere_Out)
	If nWhere_Out = 3  &&& In a Cell
		nActiveRow = Ceiling(Round((nYCoord - (Objtoclient(This,1)+;
			.HeaderHeight))/.RowHeight,0))
		*** Move the Pointer to the row
		.ActivateCell(nActiveRow,oColumnNumber)
		*** Get info from Tooltip_Info Method
		.ToolTipText = .Tooltip_Info(oColumnNumber,oColumn)
	Else
		.ToolTipText = ""
	Endif
Endwith

*!* Grid Tooltip_Info()
Lparameters pWhichColumn,poColumn
******************** Thats It.

*!* Example of code you can place in Tooltip_Info()
Lparameters pWhichColumn,poColumn
Do Case
Case pWhichColumn = 1
Return ""
Case pWhichColumn = 2
Return Alltrim(Nvl(customers.address,""))+Chr(13)+;
ALLTRIM(Nvl(customers.city,""))+Chr(13)+;
NVL(customers.postalcode,"")+". "+Alltrim(Nvl(customers.country,""))
Case pWhichColumn = 3
Return Alltrim(Nvl(customers.contacttitle,""))+Chr(13)+;
"Phone: "+Nvl(customers.phone,"")+Chr(13)+;
"Fax: "+Nvl(customers.Fax,"")
Endcase
*!* OR just return what the value is if its too large to fit in the column
*!* this is where "poColumn is used
Return Iif(Len(Alltrim(Evaluate(poColumn.ControlSource))) > 20,;
alltrim(Evaluate(poColumn.ControlSource)),"")

Or you could Indexseek() another Table And Display Info
BUT Do Not Over Load As This Runs On MouseMove() And you may Get
erratic results Or a Total slowdown

If setting relationships, Do it In the Form Load()

You could Display Info In a Window If you Like:
Instead Of ToolTipText In GridShowInfo() Use

cValue = .Tooltip_Info(oColumnNumber,oColumn)
Wait cValue Window Nowait

Again: This Is To give you an idea On how it can be done, you will have To Modify To suit
your needs.
 
Thanks again, I'll play with it tomorrow.

I'm wondering if this could be done without ActivateCell, though. Also it may be nice to use Carlos Aloatti's tooltip instead (VFP9 only). I'll send him a link to this thread.
 
Hello Ilyad:
The first answer that comes to mind is No, but I am a firm believer in anything and everything is possible in VFP. Will try to figure it out later.

On another note: I was so focused on Bindevent() and Aevents() that I missed the obvious:

All we need in Grid GridShowInfo() is:
Code:
Lparameters nButton, nShift, nXCoord, nYCoord
Store 0 To nWhere_Out ,nRelRow_Out, nRelCol_Out, nView_Out
With This
	.GridHitTest(nXCoord, nYCoord,@nWhere_Out,@nRelRow_Out, @nRelCol_Out)
	If nWhere_Out = 3  &&& In a Cell
		.ActivateCell(nRelRow_Out, nRelCol_Out)
		.ToolTipText = .tooltip_info(nRelCol_Out)
	Else
		.ToolTipText = ""
	Endif
Endwith
In tooltip_info() only 1 parameter
Lparameters pWhichColumn

if displaying the control source value:
pocolumn = Evaluate("this.column"+Transform(pWhichColumn))
Return Alltrim(Evaluate(pocolumn.ControlSource))


 
You're right and unfortunately I hadn't time to work on the idea today. I hope to be able to do so tomorrow. It is great you posted this solution.
 
Thanks again, I'll try it now. BTW, I know whom to attribute it <g> Thanks, WS.
 
Yes, the new code works a bit better. Once again, thanks.
 
Hmm, I think I already answered this thread and thanked you, but now it's gone...

Well, tank you, works nice. Have a star.

Bye, Olaf.
 
Thank You Olaf...
 
I think we need to re-think this approach as it makes navigation a bit weird. I'm using grid with editboxes for Memo field and I also use Highlight Style = 2. I like the tooltip showing, but the navigation seems all wrong, so I may need to disable this for now with this flag property.
 
Ilyad:
We dont use this; I wrote it on the spur of the moment... If you want the edit box not to have Visual persistence set the Allow Cell selection to .t..
In our app, we do not put a edit box in a grid, for the simple reason it throws all rows out of wack, we normally have an edit box next to the grid, same height as the grid, and its control source is the same table as the grid's recordsource. Every time the row changes the edit box displays the pertinent info, This makes for better readability. Another thing we do is, if there is a shortage of space, when our edit box is double clicked, it opens a larger version in a seperate form. You could do this in your grid as well. Its really pretty simple, just pass the form the Control source...
 
I'll try to play with AllowCellSelection property. In this particular form I can not really move editbox out of the grid, though, of course, for editing I have an Editbox on the form. I may try to use only first 250 chars instead and replace editboxes back with textboxes in the grid.

I'm afraid it would not solve the navigation problem with tooltips on, though.

I'm still thinking how to get cell value without activating a cell? I haven't gotten a workable idea so far.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top