INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Jobs

Image in a Grid

Image in a Grid

(OP)
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

RE: Image in a Grid

Yes, the problem is the image control has no controlsource, neither the Picture nor the new in VFP9 PIctureVal will help you to set such a construct that automatically updates. This is like a textbox would be without controlsource, only the Value property. Whatever you put there is just the value, there is no activity evaluating that value on a current record.

Therefore you have to use some trickery, knowing how VFP draws the grid. It reads the backstyle property of the control. So creating an image class with a backstsle_access method gives you the point in time, where you might set Picture to the path in your data.

So let me search for you, this is described in thread184-1738143: Image in grid in where I Define Class myImage as Image and have demo code using it.

Bye, Olaf.

RE: Image in a Grid

(OP)
Hi Olaf,
Ok, I'm reading your thread now, so am I correct that if I take my current image-subclass (imagebase) and add the method Backstlye_Access to it, I can use it as you describe with your custom class?

In the Method, add the code:

This.Picture = Evaluate(this.ImageFileName)
Return This.BackStyle

And add the property ImageFielName
To the image class as well?

So I'll try it now.

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."hammer

RE: Image in a Grid

Well, yes, mostly.

Instead of This,ImageFilename you might use your Document.Icon, the Document alias will be accessible within the code and the grid is at the record you want to display.

Also look closer, I used Evaluate(this.ImageFileName) for a reason. If you add such a property, this becomes a property quite like the controlsource (only one way, though, not writing back anywhere). If you then set .ImageFileName = "Document.Icon", then Evaluate(this.ImageFileName) will mean Evaluate("Document.Icon"), which is nothing else but Document.Icon itself. When you only use that for this one case, you can also go more directly and have Document.Icon in your code instead of going through this hoop.

Bye, Olaf.

RE: Image in a Grid

(OP)
Hi Olaf,
Making some progress, but not familiar with some of the more advanced issues.
So I have modified my imagebase class to have the Backstyle_Access() Method, and in that method I have put in

This.Picture = Evaluate(this.ImageFileName)
Return This.BackStyle

As Above. And I've added the property ImageFileName to the imagebase class as well.

But I'm tripped up on the INIT, which I believe goes into the form level init?

So I put this code into the INIT of the form:

WITH ThisForm.grdCodeField.Column3
.AddObject("cont1","ImageBase")
.cont1.IconImage.picture = 'ImageFileName'
.cont1.resize
.cont1.visible=.T.
.Sparse=.F.
ENDWITH

I think at least part of my problem here is related to the object reference? I've not used the "WITH" before, so not sure if I'm referencing it right. I had the oGrid reference first, and that gave me an undefined object, so I changed it to the reference in the form ThisForm.grdCodeField which is the name of the grid in my form. I'm also mixing between your "code" level definition, and trying to use my class library, and translating between code and "Form" feels a little awkward. Bare with me, this is new learning territory for me. How do I correct this point?

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."hammer

RE: Image in a Grid

.cont1.IconImage.picture = 'ImageFileName'

You won't set that, the code of BackStyle Access sets Picture, nothing else must do so. You have to set ImageFileName to "Document.Icon" for it to work.

Let's face it, if you had a textbox you also don't set Textbox.Value = "Controlsource", you set Textbox.Controlsource = "table.field". The Controlsource evalates its own expression and puts that in Value. Just like the Backstyle_Access() code does and evaluates ImageFilename and puts it in Picture. So it's never Picture fetching what you have in ImageFileName but its the other way around. The event of accessing the Backstyle property (which compares to refresh or record navigation in regard of the grid acessing it) is making the code put the Picture value in. Picture is just an inactive proeprty, it never is active and you also can't make it active by adding access or assing methods. The solution makes use of the grid accessing the backstyle property of an image control to check, whether the picture needs to be drawn with tansparency or opaque. The Picture itself should also be accessed, so the grid knows what to draw, but it may not access it more than once. Anyway, creating a Picture_access method will not be be called by the grid for every row. If that would be the case, you could also let Picture_access return Document.Icon directly. But that's not how it works.

So it all relies on well known grid behaviour.

Besides all this, it won't work, if your image control is in a container, then your grid.column directly contains a container containing an image control, that's never working.

Bye, Olaf.

RE: Image in a Grid

(OP)
Olaf,
I'm confused... I don't have the control in a container. I'm just following the code from your thread, but I'm struggling with understanding how it works. The "Well known grid behavior" you mention, I'm quite certain is well known to you, but completely mystery to me.

My ThisForm.Init breaks immediately when I try to run this. I'm assuming because, where you've created the form programmatically, so it all works fine "in code", I'm creating a form using the form designer, and I'm trying to use the base classes that I have already, but where your's defines these as "simple example" I am not clear on how to translate the "in-code" of this to a Form, with my base classes on it.
During the Init I get the message "Class definition IconImage is not defined".

The code is

CODE

DODEFAULT()

WITH ThisForm.grdCodeField.Column3
	.AddObject("cont1","Imagebase")	
	.cont1.Imagebase.picture = 'File Icon'
	.cont1.resize
	.cont1.visible=.T.
	.Sparse=.F.
ENDWITH 

So Imagebase (I thought) would be a reference to my image class in the baseclass library. Do I need to do something else to tell VFP that it's that class I want to create the new object in Column3 on?

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."hammer

RE: Image in a Grid

You do

.AddObject("cont1","Imagebase")
.cont1.Imagebase.picture = 'File Icon'

That just reveals if not proves, your real image control is not ImageBase, but ImageBase is a container, having an Imagebase image control, which in turn has the picture property.

So just open up "your" IamgeBase and see for yourself. What looks as one control in the designer must be an image control in a container, just looking as if it was a plain simple image control, because this has same size, perhaps.

You can't fool anybody looking precisely. You have grdCodeField.Column3.cont1.Imagebase.picture and if ImageBase would merely be based on picture, you wouldn't have that layer.

Bye, Olaf.

RE: Image in a Grid

(OP)
Ah, ok I see part of the issue here now. I was reading that thread you mentioned above, and I picked up the wrong code from it...
So now my INIT is this:

CODE

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

Where Imagebase is meant to be from my baseclasses library. But it doesn't seem to recognize my class library? Or is there something I need to do to tell it to use the image definition in that library?

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."hammer

RE: Image in a Grid

There only is one post where I define Class myImage as Image

CODE

Public oForm
oForm = Createobject('myForm')
oForm.Show()

Define Class myForm As Form
  Height = 400
  Width = 800
  Add Object myGrid As Grid With Height = 400,Width = 800,RecordSource = 'myImageList'

  Procedure Load
    Local Array aImageList[1]
    Local lcPath
    lcPath = Home()+'Graphics\Bitmaps\Offctlbr\Large\Color'
    Create Cursor myImageList (FileName m)
    For ix=1 To Adir(aImageList, Addbs(m.lcPath)+'*.*')
      Insert Into myImageList Values (Addbs(m.lcPath)++aImageList[ix,1])
    Endfor
    Go Top
  Endproc

  Procedure Init
    With This.myGrid
      .ColumnCount = 2
      .RowHeight = 24
      With .Columns(1)
        .AddObject('EditBox1','EditBox')
        .CurrentControl = 'EditBox1'
        .Width = 720
        .Sparse = .F.
        .EditBox1.Visible = .T.
      Endwith
      With .Columns(2)
        .AddObject('myImage1','myImage')
        .CurrentControl = 'myImage1'
        .Width = 24
        .Sparse = .F.
        .myImage1.ImageFilename = "myImageList.FileName"
        .myImage1.Visible = .T.
      Endwith
    Endwith
  Endproc
EndDefine

Define Class myImage as Image
   ImageFileName = ""
   Procedure Backstyle_Access()
      This.Picture = Evaluate(this.ImageFileName)
      Return This.BackStyle
   Endproc
Enddefine 

Notice myImageList is a Cursor here, not an object name. It still works as is.
You need a new Imageclass, it seems, as your's is having the surrounding container.

Bye, Olaf.

RE: Image in a Grid

(OP)
Hi Olaf,
No, there is no container on my imagebase class. 1) I checked it in the class browser, and 2) the "confusion" in the code came from the thread that you posted the above code in, from another user, but I got confused thinking his code was from a form, and not realizing he was using a container in his example. That was my fault.

So I'm looking what you have above, and I have put the LOAD code into my form's LOAD event, so it also creates the list of images (from my "CONFIG\FILEICONS" directory.
I found another mistake in my INIT procedure, where I changed "myImageList" to "Imagebase1.Filename" so that was wrong, as that would be the control name not the cursor.

I watched it in Debug, and the cursor populates perfectly, but when I get to the INIT line with .AddObject('Imagebase1','Imagebase') it fails with the error "Class definition IMAGEBASE is not found."
I know I have this class in the class library "baseclass". Do I have to somehow tell the form that is where the Imagebase object is defined?

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."hammer

RE: Image in a Grid

SET CLASSLIB is what you need.

Bye, Olaf.

RE: Image in a Grid

(OP)
Hi Olaf,
That helped. I put it just above the code in the INIT of the form, is that the best place for it?
I noticed in the Help File there is a "RELEASE CLASSLIB" THis is contained only in a small form, but should I issue a RELEASE CLASSLIB in the DESTROY() event of the Form?

This is showing the correct image in the grid, but display is a little mucked up, but I should be able to resolve that.

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."hammer

RE: Image in a Grid

OK, glad you're there.

Where you put the code depends on your needs. You know which events occur when, The grid could also do it's own init, it would have needed yet another class definition to write this in PRG code to share in a forum post. I merely do visual classes and PRG clases have a low importance other than those only available there, eg think of Session. But this leading off track.

The imagecontrol should be in your baseclasses.vcx, OK, and then you can even put this into the grid at design time without code. Just like any other control.

Bye, Olaf.

RE: Image in a Grid

(OP)
Olaf,
Thanks. I know my stupid questions and lack of understanding on the finer points frustrate you, (it frustrates me too). I know what I want the application behavior to be, but it is sometimes a very complicated hill to climb. Now that I have this one working, I can repeat it in other parts of my application. Many thanks.

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."hammer

RE: Image in a Grid

(OP)
Hi Olaf,
So it's very close now. I thought I had it down, but I think there is something I still need.

So with the GRID control set without a control source, My two leading fields "File Description" and "File Extension" are not reflecting what is in the table.
So there are 3 columns:
File Description File Extension Icon

All are held in a table called CTFILETYPES. If I set the controlsource of the GRID to CTFILETYPES, it displays the description and extension perfect, but only displays the image of the first record in each of the grid rows (in this case PDF icon). If I set that off, File Description shows "Memo" in the gird (mouse hover over it shows it's the memo field that contains the pathname of the image in Icon column). Extension is empty, and the icon shows exactly the right Icon.

Do I need to control each individual columns control source? That seems wrong, but I'm not sure how to resolve this conflict.

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."hammer

RE: Image in a Grid

Most prbably you need to set the Sparse property,see my code.

Bye, Olaf.

RE: Image in a Grid

(OP)
I set this in the form INIT:

CODE

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

But the result is the same. MEMO in first column , blank 2nd column, icon in 3rd column.

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."hammer

RE: Image in a Grid

If you don't set controlsources nothing happens.

Bye, Olaf.

RE: Image in a Grid

(OP)
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

RE: Image in a Grid

(OP)
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

RE: Image in a Grid

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.

RE: Image in a Grid

(OP)
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

RE: Image in a Grid

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,RecordSource = 'myImageList' 
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.

RE: Image in a Grid

(OP)
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

RE: Image in a Grid

You have to set the recordsource and the icon columns .Sparse has to be .F.

Bye, Olaf.

RE: Image in a Grid

(OP)
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

RE: Image in a Grid

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.

RE: Image in a Grid

(OP)
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

RE: Image in a Grid

(OP)
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

RE: Image in a Grid

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.

RE: Image in a Grid

(OP)
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

RE: Image in a Grid

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.

RE: Image in a Grid

(OP)
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

RE: Image in a Grid

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.

RE: Image in a Grid

(OP)
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

RE: Image in a Grid

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.

RE: Image in a Grid

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.

RE: Image in a Grid

(OP)
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

RE: Image in a Grid

(OP)
Dear Olaf,
NOW I GET IT. Sorry, finally. That last explanation was the gap I just didn't get until now. And it is working! (Ahhhhhh....)
While painful, I'm glad I hung in. Now I get it. Just totally missed it.

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."hammer

RE: Image in a Grid

No, you misread, Both columns "display" the same single cursor field, The column1 as text and column 2 actually is unbound, just via the myImage control it also addresses that filename memo to get the picture.

You can also have the picture first, if you set column2.columnorder=1.

This is just a demo. You can have whatever fields display in whatever columns, just the imagecontrol column should be an extra column not having a direct controlsource. You can play with the code and add a cursor field as second column and see whether that makes a change. I bet the image will just overrride the text or number or date or whatever second field of that column2, as the olumn2 only has one currentcontrol.

Bye, Olaf.

RE: Image in a Grid

(OP)
Yeah it does. In my grid, I've got 3 columns. So I saw that behavior before.

The fix in my case was simply to use the field in the table that has the image reference in it, which takes the place of the array that you create unbound. Now I get to fight with the next thing in getting the grid to look right. Have some oddity with text box in one field not aligning with the columns next to it. I changed the row height to be taller to accommodate the icon image, so will have to clean up the rest of it to get it to look right. Hopefully that's not as painful as getting it to show. :)

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."hammer

RE: Image in a Grid

Array?

Bye, Olaf.

RE: Image in a Grid

(OP)
Sorry, I meant to say "cursor".

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."hammer

RE: Image in a Grid

OK, next up: Unbound?

If you don't already have all fields you want to display or use as the source of the picture property in a table, you create a cursor by a query to be bound to the grid. Whenever you access a field of an unbound alias, the grid does not skip through its records, so you won't have that cursor alias unbound. The only unbound thing I talked of is the column of the image, not the whole grid. The image class gets the picture from the same row as other columns anyway, as the grid moves the record pointer through the cursor, so also in an unbound column, you can access the current rows fields in code like backstyle_access, which is called for every row drawn.

Bye, Olaf.

RE: Image in a Grid

(OP)
Interesting.
As I implement this in other parts of the program, I'll keep that in mind.
But after 5 days, this form is finally working 100% the way that I want it to. This has been an education in GRID, a control I've previously avoided like the plague, but now I'm starting to get a right reasonable arsenal of good features out of for use across the application.
Cheers.

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."hammer

RE: Image in a Grid

Quote (Scott24x7)

after 5 days, this form is finally working 100% the way that I want it to.

So you got it working or did you leave the image column out?

One problematic thing with images in the grid always is, that you only have one Rowheight for all rows. Havent tried setting that in backstyle_access, too, but I don't think it would work out.

Bye, Olaf.

RE: Image in a Grid

(OP)
I got it all working. Image column is in, and now I'm using the same technique in another form as well. Finally got a handle on it all. Thanks heaps for your patience with me on this.
RowHeight is now controlled by the GRID and then text boxes are set with .Textbox1.Height = This.grdControlGriid.RowHeight

So if it changes I don't have to update all of them. Since I only want icon to appear in the grid, I have control over the icon size, so I just make them all 24 height (the icon image). Then set RowHeight to 28 so there is some space between icons and rows. It works well.

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."hammer

RE: Image in a Grid

Fine, very fine.

You don't need to set ColumnX.Text1.Height, the standard text1 box in grid columns resizes flawless without any visual artifacts. Only when you set Sparse=.F. where not necessary you may get artifacts of control borders showing up in the grid cells, but the normal text1 is only a white space in the grid and autoresizes with rowheight. You can think of grid cell rendering as only drawing the inner part of controls, the white space having the value is shown, the gridlines are making up the border. Up to Vista the active column was also showing the 3d border look of controls, only in the active row, since we got the flat look since Vista, that doesn't differ. With Sparse=.F. you set a mode drawing every row in the same mode noramally only shown in current row, and the effect can be seen especially wih comboboxes then having their dropdown arrow icon either in all rows or only the active. The Spareseproperty is named after that sparsely drawing so the grid looks cleaner than an array of normal controls would look.

Overall less is more, just think about it that way: If defaults were that bad, developers would have complained and MS would have changed, up to 2007 end of life announcement the MS team was very open to suggestions from the commuity. The grid is very mature and aside of the steep learning curve involved with its binding behaviour (google "vfp grid goes blank", a famous problem), defaults are normally just fine. What is a bit of annoyance is the default in regard of deletemark, in my opinion normal users should most often not be enabled to delete rows and more important also not be able to recall (undelete) them, I would have hidden that by default. Many other defaults also are a matter of taste, some might prefer gridlines only horizontal, others only vertical, for most black is a bit too strong for the lines, this could have been a medium grey, at least there is GridLinesColor.

Anyway, keep it as it works.

Bye, Olaf.

RE: Image in a Grid

(OP)
Thanks Olaf,
I've applied your comments about the textbox and column. Yeah, it's a bit non-intuitive from my perspective how much power the Column has overall, so now that I've gone to a lot of default it's cleaner and smoother, so thanks for that advise. I'm now working on my second implementation. So far it's working good. I have the icons appearing as I want them, just a few touches on some memo field writing, nothing to do with the grid itself. Very nice outcome. The grid is I think, the steepest learning curve in all of VFP. But now that I'm getting it "tamed", it's proving very useful.

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."hammer

RE: Image in a Grid

Notice you may know the grid better than you think:

CODE

USE ?
BROWSE NAME oBrowse NOWAIT 
? oBrowse.Class 

So a browse window is a host to nothing else but a grid.

You can also learn from borwse configurations how grids will have the same binding and more.

Bye, Olaf.

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members!

Resources

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close