Friday, August 19, 2005

Visual FoxPro's Grid
It is my opinion that the Visual FoxPro grid has gotten a bum rap at times. Though it does possess it's share of eccentricities, it is probably one of the most powerful and useful controls I have ever had the pleasure of working with. The things that it is capable of doing are simply amazing. Heck, you can have multiple controls in a column or even put a grid inside a grid, so you essentially have a row/column intersect (cell) representing many records.

In this entry, I want to show you a little known feature of the grid control. If you know about this feature, then you are one of a handful. When the grid is refreshing or otherwise repainting it will access the backstyle for every control the columns contain, and anything you do in there will stick for the individual controls shown in the grid.

Some help from the MS Fox Team
Allow me to try and clarify... let's say you have a grid with a single column and that column contains Textbox1. If you set the backcolor of the Textbox1 through code to, let's say, the color Red, then every cell shown in column1 will turn red. So, how to get dynamic colors (individual cells colored differently within the same column)? Well, the MS Fox Team provides us with some dynamic properties of the column object that will act on individual cells (DynamicAlignment, DynamicBackColor, DynamicCurrentControl, DynamicFontBold, DynamicFontItalic, DynamicFontName, DynamicFontOutline, DynamicFontShadow, DynamicFontSize, DynamicFontStrikeThru, DynamicFontUnderline, DynamicForeColor, and DynamicInputMask). These are all very useful, and in the scenario I provided the DynamicBackColor will work nicely to change the backcolor of individual cells within a column of the grid. But what if you wanted to do something more complex? What if you had a container in the column and that container contained multiple objects and you wanted to set their forecolors and backcolors to completely different colors dynamically or what if you wanted to display different pictures within the grid cells?

Developers' usual and ingenious solutions
One approach to these problems is to use multiple controls within the column of the grid and then use DynamicCurrentControl to decide which to display. Such as one textbox that has a red background and another that has a white background, or different image controls all set to different pictures.

Another ingenious method some Visual FoxPro developers imploy when solving this problem is to subclass the column object and then "hook" into a non-used dynamic property of the column to use it for other purposes (Such as DynamicForeColor) If the ForeColor is being set to 1 then do this, if the forecolor is being set to 2 do something else, if the forecolor is 3... and so on. While this approach and the preceding one are both valid way of doing this, there is another way.

Another way
As previously noted, the backstyle is accessed for the currentcontrol in a column, and it's not accessed just once, it is accessed for every visible cell in the grid. So, using this we can do nearly whatever we want as far as dynamic formatting and display. Want different images displayed? Just subclass a container and put an image control within it and place it in the column. Then, in the backstyle_access method (you'll need to add this access method to the subclassed container) set the value of the contained image's picture property to a field in the recordsource that holds all the different paths in the image's backstyle_access method.

this.picture = crsImages.Paths

There's an example of doing this included in the download. When you run the example it will ask you for a directory containing images. If one is not readily available to you, you can select the folder the project is in because I have included the below screen shots in it. This solution is more efficient than having an image control in the column for each image you want displayed in the grid... 100 images = 100 image controls? I'd rather just deal with one.

Calendar class and real world example
OK, but what about something a little more real world? What kinds of things is being able to dynamically alter items within a container using the backstyle_access good for? All sorts of stuff. In order to demonstrate the just one useful example of this, I put together some quick calendar demos. I've created an advanced calendar class using the grid control. This should demonstrate well the power of utilizing backstyle_access in a grid, not to mention the power of Visual FoxPro. Below is the download link for the project source and some screen shots (so you can know what to expect). There is an executable provided in the source folder for running the examples, or if you prefer you can run the forms individually. The examples were created using Visual FoxPro 9.0, so if you're using an earlier version you will have to modify the code or better yet, upgrade! There are more great things to come, Visual FoxPro Rocks!

Download VFP Calendar Examples and Source (91 KB approx.)


Just a simple calendar


Demonstrates some of the advanced display features of the calendar class


Improved Date and DateTime controls created using the calendar class
Saturday, August 20, 2005 12:19:05 AM (Central Daylight Time, UTC-05:00)  #    Comments [26]
Wednesday, August 24, 2005 9:38:28 AM (Central Daylight Time, UTC-05:00)
WOOOW! I have seen many calendar implementations with vfp but this is by far the best!
Great job!

Thank you!

Note : I found a small issue with timepicker control. When I have typed a date in the text box and then click in the button for the picker form the form doesn't respect the date entry in the text box and this is because the monthcal's init event runs before the form's init. I resolved the situation adding a DelayedInitialization Property in the monthCal object.

Thank you again!

Vassilis Aggelakos

Wednesday, August 24, 2005 9:45:45 PM (Central Daylight Time, UTC-05:00)
Vassilis,

Thank you for the positive feedback regarding the calendar class. I also really appreciated your suggest regarding how to fix the date and datetime controls so they will respect the date that is entered in them.

Based on your suggestion and the need for the date and datetime pickers to handle empty dates and datetimes, I have made some changes to the class and uploaded a new version of vfpcalendar.zip to replace the old one.

To All,
If you wish to download the newest version of this class, you can simply redownload the zip file from the link provided in this blog entry. Special thanks goes out to Vassilis for helping me improve the class.
Thursday, August 25, 2005 2:37:09 PM (Central Daylight Time, UTC-05:00)
I 'm back again!

Your modifications in the control was a pleasant surprise for me.

This time I have 2 (small?) issues:
1. When the Enabled property is .F. for the Date/Time Picker controls the underlying controls don't look disabled. So the Enabled property of the Date/Time Picker controls must be passed on the underlying controls also if we want to have an authentic disabled control.

2. I use the DatePicker control in a form without Titlebar and the dropped-down form appears significantly lower than it should be (actually the difference is as the height of the missing titlebar! ) It seems like this case the SYSMETRIC(9) function doesn't return the height of the titlebar of the active window! but instead the height of the title of the main VFP window (the help is not so helpful here and I haven't used the function before). A quick workaround could be:

*!* PositionCalendar Method.
loCalendar.TOP = OBJTOCLIENT( THIS, 1 ) + IIF(THISFORM.TITLEBAR=1,SYSMETRIC(9),0) + THIS.txtDate.HEIGHT + ;
IIF(THISFORM.BORDERSTYLE = 3, SYSMETRIC(4), SYSMETRIC(13)) + ;
IIF(THISFORM.SHOWWINDOW = 2, THISFORM.TOP, OBJTOCLIENT(THISFORM, 1 )) + 3

Thank you very much and hope not to bother you!

Vassilis Aggelakos

Thursday, August 25, 2005 7:32:25 PM (Central Daylight Time, UTC-05:00)
Vassilis,

You're not bothering me at all. Your suggestions are sound and I am more than happy to improve any of the classes or code that appears on this blog with suggestions from members of the Visual FoxPro Community.

I've implemented the changes you've suggested here, this allows the calendar to be positioned correctly when there is no titlebar, and the control to disable its internal components when the enabled property is set at design-time.

I've also cleaned some things up that were bothering me. The calendar is now squarely centered on the form when it displays (it was slightly shifted to the left).

I've added some bindevent code so that the calendar moves with the underlying form should the user decide to move the form while the calendar is displayed. Though this is unlikely, the calendar looked really strange floating in mid-air until the deactivate code ran to release it, so this change allows the calendar to function more like an actual dropdown for the date and datetime controls.

I've also tweaked the positioncalendar methods for each control so that the calendar shows up in exactly the same position for both.

I've begun versioning the vfpcalendar.exe so I can keep better track of the incremental changes being made to the classes.

To All,

I've uploaded the newest zip and it can be downloaded from the provided link in this blog entry. If community involvement in the open source projects presented in this blog continues to grow, I will consider setting up a site where we can collectively work on them. There are other options we could explore as well, such as SourceForge. But at the moment this would be overkill, so for now I will continue to alert readers of new versions in the comments section of the blog entries.
Friday, August 26, 2005 2:36:02 PM (Central Daylight Time, UTC-05:00)
> I will consider setting up a site where we can collectively work on them.<

IMHO it is a great idea. It could be a place where the so generous VFP community stores only pure VFP Controls.

I am working on a DropDown hierarchical Combo TreeView Control based only on a grid without activex.
My plan is to make it public around in mid September.

I am sure that VFP community experts have a lot more to offer.

I stay tuned, if I can help in any way just drop me an email.
Friday, August 26, 2005 5:31:47 PM (Central Daylight Time, UTC-05:00)
Craig,

This a very good Calendar, but I have a comment to you. When you use the
controls (I tested DatePicker), you need to do some house keeping due that
allways leave the temporaly table open (one each time you choose a date with
the control).

Other enhancements you can do, is add a Today button in the control as many
of the ActiveX controls, and maybe the week number (a little bit more
difficult).

Thanks anyway for this.

Hernan
Hernan E. Delgado
Saturday, August 27, 2005 6:38:37 AM (Central Daylight Time, UTC-05:00)
Vassilis,

I'd love to see your Dropdown Treeview when you're ready to show it. If interest in these open source projects and others continues to grow within the Visual FoxPro Community then I will look at putting a site up to streamline project management.

Hernan,

Great catch... shame on me! I've added some code to the calengine's destroy event to clean up the temporary cursor. Thank you for taking the time to point this out. The Today button is a good idea and one that I seriously considered as an optional feature for the calendar class. I decided against it at the time because this blog entry was more about using the backstyle_access method to extend Visual FoxPro's grid class. However, since the calendar has been well-received (100+ downloads so far and plenty of positive feedback), I think this would make a nice feature to add to the next version of this.

I've seen the week numbers displayed on certain calendars, but I'm not sure how useful they are. They're a lot like that other feature some calendars have where they show you grayed-out days from the preceding and following months -- the feature is there, but I'm not sure how much use it gets from the users. If I begin to hear more community members asking for the feature I'll look at implementing it, but for right now I think I'll leave it on the wish list.
Friday, September 02, 2005 4:32:28 AM (Central Daylight Time, UTC-05:00)
Dear Craig,

I have been trying Datepicker in your class. It looks very good. Also, I'm a newbie in using Class.

I would like to know how to:
1. The value of Datepicker in a form, since Thisform.caldatepicker1.value is empty
2. If I enter the date in TxtDate or by click the calendar, I want to evoke a form's method to refresh the data of that day, how can I do that...

Thanks in advance!
Aaron Chu
Friday, September 02, 2005 4:46:19 AM (Central Daylight Time, UTC-05:00)
Dear Craig,

1. I'm sorry to bother you again. The value thing should be OK. But I wonder the value is not showed in Debugger?!

2. I try to put the event firing in Gotfocus, this works fine for choosing date from calendar, but not entering date in TxtDate... is there any good way to do it both way, like in Valid event?!
Aaron Chu
Thursday, September 15, 2005 2:04:18 PM (Central Daylight Time, UTC-05:00)
Hi Craig,

>I'd love to see your Dropdown Treeview when you're ready to show it.<

Finally i did it!
Earlier today I sent it in my blog.

Check it out and let me know your comments.
http://weblogs.foxite.com/vassilisaggelakos/

Thank you
Thursday, September 15, 2005 7:01:25 PM (Central Daylight Time, UTC-05:00)
Hi Craig

Why bother to put the image control inside a container before adding it to a grid column? Can you not just as easily use the image BackStyle_Access to do the dynamic formatting etc?

Regards,
Simon

Simon
Tuesday, September 20, 2005 2:48:22 AM (Central Daylight Time, UTC-05:00)
I have a Problems, My app has another Read Events y when using date control it shut down my app, Because calendar has an "Clear Event" on Destroy Events. Any way to make it work withot this problem?
Plinio
Sunday, September 25, 2005 6:18:05 PM (Central Daylight Time, UTC-05:00)
I have the same troubles that Plinio has. I tougth I had a bug or something, but now I know I am not the only one.

Hernan E. Delgado
Hernan E. Delgado
Saturday, October 01, 2005 4:49:29 AM (Central Daylight Time, UTC-05:00)
My apologies to everyone that it has taken me so long to get to these comments, I've been working non-stop and any free time I've had has been devoted to getting ready for Southwest Fox. Hope to see some of you there. Here are the replies...

Aaron Chu,

The controls are designed to be used with a controlsource. Set the control source to a variable name and then you can see the value in that variable in the debugger. Perhaps in a later version I can modify it to show in the value property... I think that is a good idea and probably how most developers would think it should work.

As for something like the valid event... the Value_Assign method should give you what you need.

Simon,

If the image is placed directly in the grid then it doesn't work. Why the image control works like this... I don't know. But placing the image control in a container solves the problem.

Plinio and Hernan,

The modifications you will need to make are as follows (be aware that since this will make the calendar modal, the user will be forced to select a date from the calendar before it will close - in other words, the deactivate event no longer fires, but I think it still works good this way)

*****************************
CalCalendar class property changes:
*****************************
ShowWindow = 0
WindowType = 1

*****************************
CalDatePicker class changes:
*****************************
*!* In cmdCalendar's click event put the following code...

LOCAL dHoldDate
Public dSelectedDate, oCalendar
*!* Code below was commented out to allow for empty dates
dSelectedDate = this.Parent.txtDate.value
oCalendar = CREATEOBJECT("calCalendar", dSelectedDate)
this.Parent.PositionCalendar(oCalendar)
BINDEVENT(thisform, "moved", this.Parent, "PositionCalendar")
oCalendar.Show(1)
UNBINDEVENTS(thisform, "moved", this.Parent, "PositionCalendar")
WITH this.parent
dHoldDate = .txtDate.Value
.txtDate.Value = dSelectedDate
.txtDate.refresh()
IF dHoldDate != dSelectedDate
this.parent.interactiveChange()
ENDIF
ENDWITH
oCalendar = NULL
RELEASE dSelectedDate, oCalendar

*****************************
CalDateTimePicker class changes:
*****************************
*!* In cmdCalendar's click event put the following code...

LOCAL dHoldDate
Public dSelectedDate, oCalendar
dSelectedDate = this.Parent.txtDate.value
dHoldDate = dSelectedDate
oCalendar = CREATEOBJECT("calCalendar",dSelectedDate)
this.Parent.PositionCalendar(oCalendar)
BINDEVENT(thisform, "moved", this.Parent, "PositionCalendar")
oCalendar.show(1)
UNBINDEVENTS(thisform, "moved", this.Parent, "PositionCalendar")
WITH this.parent
.txtDate.Value = dSelectedDate
.txtDate.refresh()
.savedatetime()
.value = .txtdatetime.value
ENDWITH
oCalendar = NULL
RELEASE dSelectedDate, oCalendar
Tuesday, October 04, 2005 12:27:29 AM (Central Daylight Time, UTC-05:00)
Hi Craig

I have since created a grid control using an image control placed directly in the grid and it works just fine. The only trick I had to play was to toggle the Visible property after clicking on the image to ensure that the change was reflected immediately. So I finally have tamed the grid to work exactly the way I wanted after years for frustration.

Thanks for your tips.

Simon

Simon White
Tuesday, October 04, 2005 2:30:01 PM (Central Daylight Time, UTC-05:00)
Plinio and Craig,

Don't forget to comment or delete the CLEAR EVENTS line

*****************************
CalCalendar class changes:
*****************************
*!*In destroy's event comment or delete the following line of code ...
*!*CLEAR EVENTS

Thanks again Craig

Hernan E. Delgado
Hernan E. Delgado
Thursday, October 20, 2005 5:07:01 PM (Central Daylight Time, UTC-05:00)
When I run this example and end it, I can't exit VFP,
can't quit, clicking on red X does nothing,
cancel all / clear all does nothing. Any suggestions?

Mike
Michael Chean
Tuesday, November 01, 2005 2:25:57 PM (Central Daylight Time, UTC-05:00)
This looks really useful. We have problems with the MS ActiveX controls unregistering themselves; this looks like an ideal replacement.
I'd like to see functionality to change the year - perhaps by turning the year caption into a drop down?

Rhodri Evans
Wednesday, November 16, 2005 8:54:35 AM (Central Standard Time, UTC-06:00)
Hey, I am still using VFP 7 - I would like to incorporate the calendar into my VFP7 program - what do I have to change (other than changing VFP...) in order for the calendar to work. Thanks - I am a newbie and would appreciate any help and I would really like to use the calendar because I like it the most compared to other calendar that I have seen. Thanks
Clement
Monday, December 05, 2005 10:43:13 PM (Central Standard Time, UTC-06:00)
Thanks Craig !!

You can find the Spanish version of this article at (Puede encontrar la versión en Español de este artículo en:)

http://www.portalfox.com/modules.php?op=modload&name=Sections&file=index&req=viewarticle&artid=97

Regards / Saludos,

Ana
www.amby.net
www.PortalFox.com
Wednesday, January 18, 2006 6:51:59 AM (Central Standard Time, UTC-06:00)
Hi Craig,

I am complete newbie to 'classes'.

I included the modifications suggested by you to Plinio and Hernan + remarked the 'Clear events' clause. Despite this, the date control is not visible on my form.

_screen.visible = .f. in my config.fpw.

If this is the cause, please advise what the fix is.

TIA.
Roger
Roger
Sunday, March 26, 2006 5:15:51 AM (Central Daylight Time, UTC-05:00)
I am sorry due to I am not that smart like all of you are and Perhaps I am bothering but my silly question is: If I want to store the result of any date picked how do I do that? How can I use that value in my Variable?

Thanks a lot!!

Ricardo!!!
Ricardo
Friday, May 12, 2006 4:21:42 PM (Central Daylight Time, UTC-05:00)
Hi,
I am too a complete newbie to 'classes'.
how I do for to do a matriz of 10x10 using your clases
===============================================
! 01 ! 02 ! 03 !
!======!======!======!
! ! ! !
! ! ! !
! ! ! !
This is an example, imagine 10x10
Hernan Serrano
Thursday, April 26, 2007 8:39:22 PM (Central Daylight Time, UTC-05:00)
I am working with this date time picker and it is working great except I need it to display AM/PM time instead of military. Any ideas?
Dea
Tuesday, August 14, 2007 4:55:51 PM (Central Daylight Time, UTC-05:00)
I would just like to say thanks very much for this calendar calendar control. My users will love it.

Nigel Ainscoe
Nigel Ainscoe
Monday, April 14, 2008 6:41:47 AM (Central Daylight Time, UTC-05:00)
Craig, I was looking for an efficient solution for displaying images in a VFP grid. I found a reference to this article on the UT. This method is great! Thanks very much!
-m@
Matt Weinbender
Name
E-mail
(will show your gravatar icon)
Home page

Comment (Some html is allowed: a@href@title, b, blockquote@cite, em, i, strike, strong, sub, super, u)  

Enter the code shown (prevents robots):


 

Archive

<October 2008>
SunMonTueWedThuFriSat
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678