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!

Single Cell Color with Alternate Row Backcolor Grid 2

Status
Not open for further replies.

David Higgs

Programmer
May 6, 2012
392
GB
My Grid uses the following code to set the Grid Row Backcolor to alternate colors.

Code:
this.SetAll("DynamicBackColor", "MyBackColor(alt_col)", "Column") 
this.SetAll("DynamicForeColor", "MyForeColor(userstatus)", "Column")

I would like "selected Cells" to be a different Backcolor for certain conditions. If I use the following Code and the conditions are met, the Backcolor changes. However the remainder of the Cells in the Column lose their Alternate Backcolors.

Code:
This.area.Dynamicbackcolor="IIF(AREA ='TL02',RGB(255,0,0),RGB(255,255,255))"

Is there anyway to restore alternate colors to the others Cells?

Regards,

David.

Recreational user of VFP.
 
So, if the cell meets the condition (Area is TL02), you want it to be red; if doesn't meet the condition, you want the colour to be generated by your MyBackColor() function. Is that correct?

If so, then you would first need to set the DynamicBackColor of the Area column like this:

Code:
This.area.Dynamicbackcolor="IIF(AREA ='TL02',RGB(255,0,0),MyBackColor(alt_col))"

However, that would clash with the SetAll method, which will overwrite the above setting. So instead of this:

Code:
this.SetAll("DynamicBackColor", "MyBackColor(alt_col)", "Column")

you need to set the DynamicBackColor of the individual columns:

Code:
This.Colum1.DynamicBackColor = "MyBackColor(alt_col)"
This.Colum2.DynamicBackColor = "MyBackColor(alt_col)"

and so on, but being sure not to do that for the Area column.

Aologies if I have misunderstood the requirement.

Mike




__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Hello Mike,

Thank you for your reply.

Mike Lewis said:
This.area.Dynamicbackcolor="IIF(AREA ='TL02',RGB(255,0,0),MyBackColor(alt_col))"

The above line achieved the result that I was looking for, Alternate Row Colors with a Red Background Color for a Cell that met the Condition; I was thinking along the same lines. I was wondering if RGB(255,255,255) could be replaced by a "variable" but I had difficulty in trying explain my thoughts.

Many thanks again for your assistance. I can now move on to adding other "Conditions" to the Grid.

Regards,

David.

Recreational user of VFP.
 
Glad to have helped, David.

Another very minor point. You can save yourself a few keystrokes, as follows:

Instead of[tt] RGB(255,0,0)[/tt], you can simply say [tt]255[/tt]. And instead of [tt]RGB(255,255,255)[/tt], you cam say [tt]-1[/tt].

In other words, instead of something like this:

[tt]....DynmicBackColor = "IIF(AREA ='TL02',RGB(255,0,0),RGB(255,255,255))"[/tt]

you can do this:

[tt]....DynmicBackColor = "IIF(AREA ='TL02', 255, -1)"[/tt]

It's not relevant to your question, and not worth changing what you've already done, but for me anything that can save a bit of typing is worth knowing about.

Mike






__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
I guess you only have a problem of order.

SetAll sets all dynamicbackcolor properties. All columns. And it runs for all rows, so it will be done for all cells.

When you override that call in one specific column, and you set the "else" color to RGB(255,255,255) that's white, it's neither transparent, nor neutral, nor mixes with the previous expression, you have to do that.

So yes, you put in the expression you had set before to let that work. And in case that expression is just set in the line before it's simple to keep exactly the same expression, instead of RGB(255,255,255) you keep "MyBackColor(alt_col)"

Notice: DynamicBackColor is NOT a color property, it is a property for storing CODE, an EXPRESSION, that is evaluated for every row and its return value is set to BACKCOLOR. The IIF you typically use is constant, what is dynamic is the result and thus the resulting BackColor. It's called DynamicBackColor because it dynamically determines the backcolor, not itself.

I guess even if I managed to untie some knots, I may have added some more new knots and everything more I sa will just complicate that.

Just notice for an expression with more than 2 colors you better do what you already had before and call some function, which then can have much better readable and understandable code than nested IIFs. There also is ICASE(), by the way, but if the conditions are complicated you better have a function or also grid method or form method you call from the DynamicBackcolor.

Bye, Olaf.





Olaf Doschke Software Engineering
 
Olaf said:
I guess you only have a problem of order.

Yes, I realised the importance of 'Order' as my Grid consisted of Alternate Row Back Colors. When I introduced the additional Column Colors with multiple expressions I couldn't work out what to do with the ELSE part of the 'expression' to keep the other Rows in Alternate Row Back Colors. Mike sorted that issue for me.

Olaf said:
I guess even if I managed to untie some knots, I may have added some more new knots and everything more I say will just complicate that.

That you for the further explanation, I managed to keep up with you!

Olaf said:
Just notice for an expression with more than 2 colors you better do what you already had before and call some function, which then can have much better readable and understandable code than nested IIFs. There also is ICASE(), by the way, but if the conditions are complicated you better have a function or also grid method or form method you call from the DynamicBackcolor.

This is the current state of play.

Code:
*                                                         
*	Background Colour  -  Refer to 'FUNCTION' in main.PRG 
*                                                         
																									
	this.SetAll("DynamicBackColor", "MyBackColor(alt_col)", "Column") 

	*this.SetAll("DynamicBackColor", "MyBackColor(wab_status)", "Column") 

*                                          
*	Background Colour  -  Individual Cells 
*                                          

	This.LgSq.Dynamicbackcolor="IIF(Lg_Sq = 'B' OR Lg_Sq = 'X',RGB(255,0,0),MyBackColor(alt_col))"	&&	Large Square Required 
	This.SmSq.Dynamicbackcolor="IIF(Sm_Sq = 'B' OR Sm_Sq = 'X',RGB(255,0,0),MyBackColor(alt_col))"	&&	Small Square Required 

	This.an_activity.Dynamicbackcolor="IIF(an_activity = 'X',RGB(255,0,0),MyBackColor(alt_col))" 	&&	Annual Activity Award 
	This.Book_awd.Dynamicbackcolor="IIF(Book_awd = 'X',RGB(255,0,0),MyBackColor(alt_col))" 			&&	Book Numbers Required 
	This.DecAwd.Dynamicbackcolor="IIF(Dec_awd = 'X',RGB(255,0,0),MyBackColor(alt_col))" 			&&	Decade Award   		  


*                                                        
*	Foreground Color  -  Refer to 'FUNCTION' in main.PRG 
*                                                        

	this.SetAll("DynamicForeColor", "MyForeColor(userstatus)", "Column")

	*this.SetAll("DynamicForeColor", "MyForeColor(wab_status)", "Column")
	
*                                          
*	Foreground Color  -  Individual Cells  
*                                          

	This.LgSq.Dynamicforecolor="IIF(Lg_Sq = 'B' OR Lg_Sq = 'X',RGB(0,0,0),MyForeColor(alt_col))"	&&	Large Square Required 
	This.SmSq.Dynamicforecolor="IIF(Sm_Sq = 'B' OR Sm_Sq = 'X',RGB(0,0,0),MyForeColor(alt_col))"	&&	Large Square Required 

	This.an_activity.Dynamicforecolor = "IIF(an_activity = 'X',RGB(0,0,0),MyForeColor(alt_col))" 	&&	Annual Activity Award 
	This.Book_awd.Dynamicforecolor = "IIF(Book_awd = 'X',RGB(0,0,0),MyForeColor(alt_col))" 			&&	Book Numbers Required 
	This.DecAwd.Dynamicforecolor = "IIF(dec_awd = 'X',RGB(0,0,0),MyForeColor(alt_col))" 			&&	Decade Award

Thanks again for your input, much appreciated.


Regards,

David.

Recreational user of VFP.
 
What you could do to simplify things is make the MyBackColor() and MyForeColor() functions parameterless - almost. I'd also make them methods of the grid or the form at least, so they are encapsulated.

Independent on having a grid or form method or a PRG or function within a PRG you are always called in the context of the current record displayed, so no need to pass in values, you can simply read fields from the current workarea.

What you don't know without any parameter is which column is calling, That's why I said almost. Make that a parameter like I did here in Grid Init by going ForEach column instead of using SetAll:

Code:
oform1=NEWOBJECT("form1")
oform1.Show(1)

*************************************************
*-- Form:         form1 (...griddynamics.scx)
*-- ParentClass:  form
*-- BaseClass:    form
*-- Time Stamp:   07/15/18 10:14:01 AM
*
DEFINE CLASS form1 AS form

   ADD OBJECT grid1 AS grid WITH ;
      Left = 12, ;
      Top = 12, ;
      RecordSource = "crsGrid", ;
      Name = "Grid1"

   PROCEDURE dynamicbackcolor
      Lparameters tcColumnName

      Local lnColor, lnBrightness

      With GetPem(Thisform.Grid1,tcColumnName)
         lnBrightness = Max(256-.ColumnOrder*Max(Int(128/Thisform.Grid1.ColumnCount),1),0)
         lnBrightness = Min(lnBrightness,255)
         lnColor = Rgb(lnBrightness,255,lnBrightness)
      EndWith

      Return lnColor
   ENDPROC


   PROCEDURE Load
      Create Cursor crsGrid (f1 int, f2 int, f3 int, f4 int, f5 int)
      Append Blank
      Append Blank 
      Append From Dbf("crsGrid")
      Append From Dbf("crsGrid")
      Go Top
   ENDPROC

   PROCEDURE grid1.Init
      For Each loColumn in This.Columns
          loColumn.DynamicBackColor = "Thisform.DynamicBackColor('"+loColumn.Name+"')"
      EndFor    
   ENDPROC
ENDDEFINE
*
*-- EndDefine: form1
**************************************************

You can move columns now and still the coloring will stay with a gradient from left to right as it doesn't depend on the initial column number but the column order.

To explain a bit more: GetPem(Thisform.Grid1,tcColumnname) is the ColumnObject. So you can access any column property in the WITH...ENDWITH block, not only the ColumnOrder, you can make your color computation depend on any filed of the grid cursor and on the column .Name or .Controlsource or anything else.

Bye, Olaf.

Olaf Doschke Software Engineering
 
Olaf,

Thank you for your reply and explanation of your Code; I was impressed with the results! I will experiment with the Code
with a view of incorporating some of it's principles within my Application.

The shading of the Grids Backcolor reminds me of another Procedure that I would like to see incorporated in my application
although I don't know if it's possible. Imagine a Pageframe running from Top to Bottom on the Left of a Page with just the
Tabs showing. When the mouse hovers over one of the Pageframe Tabs, the Tab slowly expands to its full size and slowly returns
to the closed position when LostFocus occurs. I will start another thread on this new subject at some stage.


Regards,

David.

Recreational user of VFP.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top