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

Image in grid

Status
Not open for further replies.

AlastairP

Technical User
Feb 8, 2011
286
AU
I am trying to display one of two images in a grid where the value in the field is either 0 or 1
I have an image control within a container

The image control does not display an image. I know there are other ways of doing this, but I would like to solve this one

Code:
WITH oGrid.frame.grid1.column1
	.AddObject("cont1","mailitem")						
	.CurrentControl="cont1"
	.cont1.resize && Centre the image control 
	.Sparse=.f.	
	.controlsource='IIF(cTemp.nRead =0,.cont1.image1.picture = "..\graphics\Images\email.png",;
           .cont1.image1.picture ="..\graphics\Images\email_open.png")'
ENDWITH
 
At first glance, I guess you missed a
.cont1.visible=.T.

Respectfully,
Vilhelm-Ion Praisach
Resita, Romania
 
Putting an IIF() function in the control source won't work in this case. Better to use the DymanicCurrentControl property:

- Add two image controls directly to the column - not in a container.

- Name the image controls, say, imgEmail and imgOpen. Those are the names of the controls, not of the image files.

- Set the Picture property of each of the image controls to point to the relevant file.

- Set the column's DynamicCurrentControl to [tt]IIF(cTemp.nRead = 0, "imgEmail", "imgOpen")
[/tt]
For a useful example, see this article: (the section headed "Showing different images in different rows").

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
I forgot to mention ....

When setting the DynamicCurrentControl, the value should be a string, not an expression, and should therefore be enclosed in string delimiters, such as double quotes:

[tt]"IIF(cTemp.nRead = 0, 'imgEmail', 'imgOpen')"[/tt]

(I'm sure you already knew that, but I thought I would make it clear.)

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
You can't execute commands or make variable assignments in IIF.

IIF(cTemp.nRead =0,.cont1.image1.picture = "..\graphics\Images\email.png",...)

This fails the same way as IIF(1=1,_vfp.caption="One is one",_vfp.caption="One is NOT one!!!")
The captions stays as it is, the assignment isn't executed, instead this is evaluated as a boolean expression, and since _vfp.caption is neither "On is one" nor "One is NOT one!!!" this results in .F. no matter how you change 1=1 to .F. or .T.

? IIF(.T.,_vfp.caption="One is one",_vfp.caption="One is NOT one!!!")
? IIF(.F.,_vfp.caption="One is one",_vfp.caption="One is NOT one!!!")
? _vfp.caption="One is one"
? _vfp.caption="One is NOT one!!!"

This is the consequence assignments and comparisons have the same operator =.

Bye, Olaf.
 
Another point: You can only assign danymic values to dynamicXYZ properties and only the grid column does have these, the picture property is not like this. Also this code doesn't run rightaway, you specify expressions which are evaluated later and not in the context of your WITH...ENDWITH. So also in these two aspects your code fails. It just doesn't error.

Bye, Olaf.
 
I would simplify the dynamic control expression to use a UDF rather than
an IIF()

Code:
thisform.grid1.DynamicCurrentControl="ImageOrEmail()"

Function ImageOrEmail
   Private m.MyString
   If cTemp.nRead=0
      m.MyString = "imgEmail"
   else
      m.MyString = "imgOpen"
   EndIf
Return(m.MyString)

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are not good for you.
 
It's also possible to only have one image control, if you define a class that implements backstyle_access:

In code this can be as short as:
Code:
Define Class myImage as Image
   ImageFileName = ""
   Procedure Backstyle_Access()
      This.Picture = Evaluate(this.ImageFileName)
      Return This.BackStyle 
   Endproc
Enddefine

The code sets the picture and to be able to support any table with different field names, this isn't hard coded but you set the table.field name into the ImageFileName property and that is then evaluated.

A sample usage of this image control could be as follows:
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

This doesn't need any of the Dynamic properties of the grid columns.

Bye, Olaf.
 
Thanks Mike, got that to work. I used image control in a container, which enabled me to centre the image in the container nicely
The only thing I encountered is that I could not set the picture property when adding the image control to the column.
The image is only visible if I have the picture property assigned in the container class in design time instead of when the control is added to the grid column

Code:
WITH oGrid.frame.grid1.column1
	.AddObject("cont1","mailopen")		
	.AddObject("cont2","mailclose")
	.removeobject("text1")
	.cont1.resize
	.cont2.resize	
	.DynamicCurrentControl = 'IIF(Z_EmailInbox0001.nRead =0, "Cont1", "Cont2")'
	.Sparse=.f.	
ENDWITH 					
WITH oGrid.frame.grid1.column2
	.AddObject("cont1","mailBlank")		
	.AddObject("cont2","mailAttach")
	.removeobject("text1")
	.cont1.resize
	.cont2.resize	
	.DynamicCurrentControl = 'IIF(Z_EmailInbox0001.nAttach =0, "Cont1", "Cont2")'
	.Sparse=.f.	
ENDWITH

download.aspx


 
 http://files.engineering.com/getfile.aspx?folder=dd668235-bebc-42a4-b3b4-6ae951bf3fcb&file=Sample.jpg
Yes, you now change which control is displayed dynamically, but the control itself must have a static picture, so you must set the picture once, either at design time, or directly after adding it:

WITH oGrid.frame.grid1.column1
.AddObject("cont1","mailitem")
.AddObject("cont2","mailitem")
.removeobject("text1")
.cont1.image1.picture = 'picture for mailopen'
.cont1.resize
.cont1.visible=.T.
.cont2.image1.picture = 'picture for mailclose'
.cont2.resize
.cont2.visible=.T.
.DynamicCurrentControl = 'IIF(Z_EmailInbox0001.nRead =0, "Cont1", "Cont2")'
.Sparse=.f.
ENDWITH
WITH oGrid.frame.grid1.column2
.AddObject("cont1","mailitem")
.AddObject("cont2","mailitem")
.removeobject("text1")
.cont1.image1.picture = 'picture for blank'
.cont1.resize
.cont1.visible=.T.
.cont2.image1.picture = 'picture for attachment'
.cont2.resize
.cont2.visible=.T.
.DynamicCurrentControl = 'IIF(Z_EmailInbox0001.nAttach =0, "Cont1", "Cont2")'
.Sparse=.f.
ENDWITH

Also:

If you add anything at runtime via code and the AddObject() method, you have to set it's visible property .t.
The grid has the unconventional behavior of showing even invisible things, but they only behave right, if you set visible=.t.

As a demo, why this is important, do this:

Code:
_screen.addobject("label1","Label")
_screen.label1.caption="Hello, I'm here"

This will add a label to screen, but you'll only see it, if you set it visible:
Code:
_screen.label1.visible = .T.

This is needed, even though the default value of label.visible is .T. already. That's why I added the cont1/2.visble=.T. lines above.

Bye, Olaf.
 
Thanks Olaf, I am aware that when adding objects the visibility must be set to .t.
However, as far as I can tell, when adding a control to a grid, it seems the visibility is automatically set to .t.
When I was bugging this out, I set the border of the container visible and the backstyle to a solid colour.
I was able to clearly see the container and that the container was being switched dynamically, just the image control would not display the image
(Just the grey control with the x lines we see with an empty image control) This was without setting the visibilty of the container to .t.
Anyway,its working with the above method for now.
I will experiment with your suggestion as I would prefer to have only one image class, not multiples as would be required with the current solution




 
It's as I said, the grid draws invisible things, too. It doesn't set visibility .T. automatic. In case of images that's sufficient. But if you add a checkbox, you can see it but not use it. That already has cost me quite some time, as neither Readonly nor Enabled was set wrong, the cursor/table wasn't readonly etc. Only visible was .f., and that was the last thing I suspected.

Bye, Olaf.
 
>I will experiment with your suggestion as I would prefer to have only one image class, not multiples as would be required with the current solution
As I showed you you can set the pictures at runtime, too, so also that isn't true.
But you'll have four mailitem objects in the grid instead of two myimage objects.

I'm not sure whether this would also work with an image control inside a container. You would then either program container.backstyle_access or you'd set image.Stretch = 1 to get the picture resized to the grid cell size isometric (with same aspect ration) or Stretch=2 to stretch to the grid cell size.

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top