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 Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Image in a Grid 1

Status
Not open for further replies.

Scott24x7

Programmer
Jul 12, 2001
2,795
10
38
JP
Hi All,
I've been reading through some old posts for a solution, but it seems everyone approaches this a little differently.
So I have a table of documents, and I wanted to be a bit "clever" and show the icon associated with the file type. (Word, Excel, PDF, etc). The types are defined in another table that has the file type, extension and icon image associated with it.

So this means each document has a memo field which holds the path to the image type for the "icon" (We made them ourselves, not trying to retrieve them dynamically thought that would be really cool).

So I set up a 3 column Grid: Filename Extension Icon

In column 3 I removed the text box, and put in an image object instead. However, in the Image properties I tried to set Document.Icon (a memo field in the table that has a fully qualified path to the image location, such as T:\MyApp\Configs\FileIcons\Excel2007.PNG

I had expected that as the records were added to the row, the image class would show that .PNG automatically, just like when I point it's picture clause to This.Picture = Document.Icon. While that works at the form level, it doesn't work in a grid... how do I get this to show these by reference to the memo field? Most of the "solutions" I saw were hard coding image types into a field and using dynamiccontrol, but that seems to just pick between differently defined image objects in the column, and I have far to many file type icons for that... Plus I want the addition of new icons to be driven by our "FileType" table, instead of having to code them.


Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
So it should be something like:

WITH ThisForm.grdCodeField.Column1
.CurrentControl = "Text1"
.ControlSource = CTFILETYPE.FILEDESCRIPTION
.Sparse = .T.
ENDWITH

I'm just not used to setting these programmatically. When I set it in the grid itself nothing happened.
I'll try this now.

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
That gives me an error saying

The data source for this object must be a variable reference.
".ControlSource = CTFILETYPE.FILEDESCRIPTION"



Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Don't pay attention to the error text, it's wrong, you can of course set a controlsource to a field, you know and are used to it. Just look very close what's missing. I won't tell you, because it really is so simple, that you must see it.

Why don't you go with what you are used to? Set the controlsources at designtime via the visual designers and the property sheet of the grid and the grids columns and controls. You don't need to go the route of setting it with code at all. Code is only necessary for a) posting in textform and b) when you need variable values.

Bye, Olaf.

 
Hi Olaf,
Yeah, I found the missing issue. :)
BUT... it didn't fix my problem.

.ControlSource = CTFILETYPE.FILEDESCRIPTION

replaced with

.ControlSource = "CTFIELDTYPE.FILEDESCRIPTION"

But when I do this, it's the same effect as if I set it at design time in the visual class property of ControlSource set to CTFILETYPE.FIELDDESCRIPTION

So in other words my grid displays all the icons 100% correctly as you guided but the other two fields repeat in every row as whatever is in the first row. So Acrobat is the first file type, and it's extension is of courese PDF. So all Description columns display "Acrobat" in the text field, and Extension all say "PDF" but the Icon is correct for the record. So weird. I tried to change .SPARCE to both .T. and .F. but they resulted in same outcome. Any ideas?

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Did you set the grid recordsource to ctfieldtye? Even if you set all single controls controlsources, that doesn't make ctfieldtype the grids recordsource.

If you look at my example adding the grid via:
Code:
Add Object myGrid As Grid With Height = 400,Width = 800,[highlight #FCE94F]RecordSource = 'myImageList'[/highlight]
That's were the grid get's its workload from. If you don't do that, the grid won't move record pointer in this table, thus showing the same record over and over again.

Bye, Olaf.

 
Hi Olaf,
Well I assume that is the same as setting the RecordSource property in the visual object at design time. I have done it there, and as you suggested in code, and the result is the same. With the RecordSource set to CTFILETYPE, then the FILEDESCRIPTION and FILEEXTENSION fields display accuratly in the grid, but the icon is only the first one (PDF) repeated across all entries. If I turn that off, the Icons are all correct, but the data fields just display the entry from the first entry... vexing.

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
You have to set the recordsource and the icon columns .Sparse has to be .F.

Bye, Olaf.
 
Yes, they are all set to sparse.

Code:
SET CLASSLIB TO CLASSES\BASECLASSES.VCX
*
This.grdCodeField.RecordSource="CTFILETYPE"
WITH ThisForm.grdCodeField.Column1
	.ControlSource = "CTFILETYPE.FILEDESCRIPTION"
	.Alignment = 0
	.Text1.Alignment = 0
    .Sparse = .F.
ENDWITH
*
WITH ThisForm.grdCodeField.Column2
	.ControlSource = "CTFILETYPE.FILEEXTENSION"
	.Alignment = 0
	.Text1.Alignment = 0
	.Sparse = .F.
ENDWITH
*
WITH ThisForm.grdCodeField.Column3
	.AddObject("Imagebase1","Imagebase")
    .CurrentControl = 'Imagebase1'
    .Width = 24
    .Sparse = .F.
    .Imagebase1.ImageFilename = "myImageList.FileName"
    .Imagebase1.Visible = .T.
ENDWITH
[/CODE}

This is the form INIT code.
Grid on form has also had object Sparse property set to .F.

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
You don't need to set all to sparse. My example only had that, as one column was an Editbox (needing non sparse display) and one was an icon (needing non sparse display).

Just scrap it and do it again. Have a normal grid, set the recordsource only and leave columns as they are. Finally only act on the icon column with your editing, either with code or in the designer, the only things needing change are text1 is replaced with the imageclass, currentcontrol is set to the imagecontrol, sparse is .f. and of course the .ImageFilename is set.

Bye, Olaf.
 
Ok, will try it as new one. Does it make a difference if I remove the Text1 from column3 in the visual class? Or should I pull it in code at the init? Make any difference?

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Hi Olaf,
So I rebuilt the entire form from the ground up, as you suggested, and still once the RecordSource of the table is set to CTFILETYPE, all the icons show only ADOBE PDF in the grid, while the Description and Extension fields who correctly. If I take the Record Source off, then the icons show correctly, but the firs field (File Type) shows MEMO, the extension field is empty, and the icon field is correct for the associated record (as verified by the memo contents.

So something still amiss...
Any suggestions?

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
I thought of redoing the grid and not the whole form. Something must mess things up. Can you simply create a new project with a new form with a new grid and bind your data there? Your first attempts should not be influenced by side effects of anything else.

In general, I can't really believe you mainly bind to the filetypes table, your main binding will be to any table listing many files. Either you join that with CTFiletype data or you set a relation of the main table to CTFiletype, whatever suits you best. If your grid would really bind to CTFiletype you would only list all file types each once. That you have the same icon all over is a sign you have both sparse .f. (correct) but don't iterate CTFiletype records (wrong), so your initial binding of Recordsource must later be overridden.

Like a report, a grid only has one main driving alias and what you do seems to be binding to multiple aliases. Use SQL, create one grid cursor, that's the best way to handle the grid in the same manner as it is handling a report.

Bye, Olaf.
 
Hi Olaf,
I've been looking closer at the code from the INIT, and I think maybe there is a misunderstanding of what I'm trying to achieve, versus what your solution provides. So I've a couple of questions to see if I understand what it means:

WITH ThisForm.grdCodeField.Column3
.AddObject("Imagebase1","Imagebase")
.CurrentControl = 'Imagebase1'
.Width = 60
.Sparse = .F.
.Imagebase1.ImageFilename = "myImageList.FileName"
.Imagebase1.Visible = .T.
ENDWITH

So the "magic" happens in the .Imagebase1.ImageFilename = "myImageList.FileName"

If I understand this correctly, the .Imagebase1.ImageFilename is being fed to it by the cursor myImageList.FileName
That would mean there is a unique image for each entry in the table, right?

But that's not my case. I have 1000 records that share one of 11 images. The image for that record gets fed again, where this case assumes that the image in the row is matched to the cursor, right?
I think this is where the problem is...


Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
In my case, I only have on cursor myImagelist. It doesn't matter, if an image appears once or multiple times, as this list is generated from a directory that's not the case, but doesn't matter.

What matters most is that all data you want to display including the image file name is in the one grid cursor only, unlesss you want to complicate the matter with a relation.

The magic does not happen in the ImageFilename property, the value of that always stays "myImageList.FileName", what changes is the record pointer within myImagelist, and thus what changes is Evaluate(this.ImageFileName) which is Evaluate("myImageList.FileName") and that is simply myImageList.FileName, so actually the image control Picture property is set to the current records value of myImageList.FileName as the grid scans through its rows. And the ImageFileName property acts exactly as a ControlSource property would act. The grid accesses the backstyle property for each row it draws, just like a columns text1 will access it controlsource for each record and displays its record value.

The only thing not happening is, when the Pictrure property would change, this wouldn't be written back to the myImageList.FileName field. So .FileName acts just like a one way Controlsource (readonly).

The grid recordsource has to be the data you want to display, but this must have a field storing the image filename. If you instead have an image ID, then join the file name in.

So let's assume I would have a product list and each product has a productcategoryID, and another table of productcategories with an image filename, then to diaplay products with category pictures, I'd SELECT products.*, category.picturefilename FROM products left join productcategories as categories on products.productcategoryID = productcategories.ID into cursor gridcursor and the myImage.ImageFileName would be set to "gridcursor.picturefilename".

Bye, Olaf.

 
Ok, narrowing down issues.
I'm using the form's Data Environment to set the table and alias the table. Would that have any impact?

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Not in any more special way as always. The typical RecordSourceType of a grid is the alias. If it is set to Table you'd have to set the DBF filename. This doesn't depend on how you open the table with DE or USE or Cursoradapter inside DE or as a separate class. No matter what.

Bye, Olaf.
 
Well, I'm totally stumped then. This is another one of those issues I've now spent more than 5 days on without it working... 1/2 and 1/2. Either I get file and extension, or I get icon, but I can't get both. Why in the world did they make this object so difficult to work with... (That's rhetorical).

I hate it, but I think I'm just going to give up on this. I'm no closer now than I was 5 days ago.

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
You just have to have both your text data and the filenames in the same alias. The RecordSource can only be one alias and fields of it.
If you have your text data in one table and filenames in another, you need to do a query in forms DE, load or init or grid init - well, anywhere before the grid becomes active (remember form.BindControls) - and set grid.recordsource to its result cursor=alias name.

Bye, Olaf.
 
Notice one more thing: The Cursor myImageList only has one field, while I set up my grid to have two columns.

Create Cursor myImageList (FileName m) <- one field (memo is making an editbox necessary, but the file name can also be stored in char and normally will not be displayed anyway, doesn't matter)

- but -

With This.myGrid
.ColumnCount = 2
...

So (of course) the images go into an extra column.

Bye, Olaf.
 
So if I understand this, the content of your editbox is a memo in your cursor (field1) and the image is the path reference to the image file in the second column of the cursor, so you have only 1 control source?


Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top