Oct 1, 2006

Listgrid - update 3

In this third update of the listgrid control, it is possible to change the grid's record source at run time. There is a new 'Open file' button in the example form that shows how.

Further, to solve the second issue in the post of july 30th, the width of the rightmost column in the grid is now changed to span the gap that normally appears when the total with of the visible columns are smaller than the grid's width. There is a new method Setrightmostcolumnwidth that takes care of this.

An updated download is available here (ZIP compressed file, 45 kb).

For more info about the Listgrid control, see the original post of July 16.

Sep 29, 2006

A resize grip on a Foxpro form

As a visual clue that a form can be resized, many forms have a 'resize grip' in the lower right corner. Visual Foxpro does not have native support for showing a resize grip on a form. But that won't stop us, we can make our own!

Over here you can download a zip file containing a resizer class. It's based on a container class and constructs it's own grip shape (Windows XP style). Just drop the class on a form and add This.resizer1.resize to the forms resize method. An example form is also included, which looks like this:

Sep 2, 2006

Images in a VFP grid class

In the listgrid class in this blog, it is possible to have different images in the cells of the same column in a grid. This is done using the DynamicCurrentControl feature and works great if there are only a few images.
When you have a lot of images to show, it seems like a bad idea to add even so much image controls to the grid column.
Luckily, there is another way to do the same. I found out about this here while working on the listgrid class. It works by creating a container class which is used as the control for the column. In the container class itself, you create an access method for the backstyle property of the container (open the class, go to the Class pad in the Foxpro menu, select Edit property/method and check the Access Method for the backstyle.
Then, in the access_method itself, you put code like This.picture = Mytable.Image, where Image is a text field in Mytable used as the grid recordsource. The text field contains the names of the images to use, which can be found on disk along the VFP path.

You can download an example here as a zip compressed file (9.6 Kb). Run the example form and look at the code in the example class. This is how it looks:

Jul 30, 2006

Listgrid - update 2

When using the vertical scroll bar to move through the grid, there where problems with the screen painting. Screen painting issues are also mentioned in VFP's help about the Scrolled event. However, it's now solved by changing some code in the Scrolled event of the grid.

I also found two new issues to think about:
1) You can select/deselect the current record with Ctrl+mouse click. However, when you move away from the this record by using the down or up arrow keys, the previous or next record is selected, but keeps the selected/deselected state of the previous record.
2) When there are multiple records selected and you move to the right most column in the grid, there is allways some space at the right. You can see there that the inverted color of the current record continues in this 'empty column', but the other selected records don't.

An updated download is available here (ZIP compressed file, 44 kb).

For more info about the Listgrid control, see the original post of July 16.

Jul 17, 2006

Listgrid - update

The listgrid control stopped responding, when you kept the Shift+Dn or Shift+Up keys pressed for a little while (in order to select multiple records). A 'thisform.draw' in the keypress event of the grid seems the solution to that problem.
An updated download is available here (ZIP compressed file, 44 kb).

Jul 16, 2006

Listgrid - a grid acting like a listview

A few month back, I decided to follow up on some ideas to make the VFP grid control act like a multi-select listview. In my applications I often use the MS listview control for this, but since MS stopped development on their core OCX controls, the listview control is beginning to show it's age with Windows 2000 style column headers in a XP world. The objective is to copy as much of the functionality of the MS listview. I just want to try how far this goes. If it doesn't work out, I'll switch to another third party OCX control. Here it is as it looks now:



Features
The class has the following features:

  1. Multiselect option (set multiselect to .T.), using standard Windows keys (Shift, Ctrl combinations).
  2. Sorting columns.
  3. Have Pictures in columns.
  4. Save and restore reordered columns, column widths and the column which was last sorted.
  5. Export to Excel.
Quick start

  1. Drop the class on a form.
  2. Resize the container of the class to the desired size. The grid inside it will automatically size accordingly.
  3. Set the recordsource property to the desired table/view/cursor.
  4. Put code like this in the init method of the form:
    IF !USED("CUSTOMER")
    USE CUSTOMER IN 0
    SELECT CUSTOMER
    ENDIF
    This.lGrid1.Multiselect = .T. && multiselect if desired
    This.lGrid1.RecordSource = ALIAS()
    This.lGrid1.initialise()

  5. Run the form.
Listgrid table
There is a table called Listgrid, which contains column information for every recordsource used in the Listgrid class.
The table is created if it does not allready exists and updated automatically with default column
information for each recordsource opened by the class.
In the supplied Listgrid table, there is allready information about the example Customer table.
You can alter the data in the table, so you can have calculated fields and pictures in the grid.

  1. Table: contains the same name for all records belonging to a certain recordsource
  2. Controlsrc: you can see there are options to create a controlsource expression for every column
  3. Fieldtype: data type of the column. You can use a 'P' for pictures
  4. Fieldwidth: width of the field, not used by the listgrid class itself
  5. Decimals: decimals of the field, not used by the listgrid class itself
  6. Descript: shows up in the column header
  7. Alignment: alignment of the header. 0 = left, 1 = right
  8. Disporder: set the order in which the columns are shown
  9. Visible: .False. for columns that must not show up
  10. Colwidth: column width in pixels
  11. DispinXLS: the column shows up in the Export2Excel option of the class
  12. Images: list of images used for FieldType = "P"
Pictures
You can do the following to create a column with pictures in it:

  1. In the field images in the listgrid table, create a comma separated list of the images to use in the column. Just the filename is enough, as long as the images themselves are along the VFP path.
  2. In the field Controlsrc create an expression which returns a text 'Image1', 'Image2' , 'Image3' , etc. for the image you want to show up. For example:

    IIF(MyField = "Man", "Image1", IIF(MyField = "Woman", "Image2", "Image3"))

    Whenever the text in the field is "Man", the first image in the list shows up, for "Woman" the second, otherwise the third image.
Export to excel
To demonstrate the multiselect feature, there is a ExportToExcel method in the class to show the data of selected records in an Excel sheet. In the Example form, only the selected records show up in Excel with the optional where clause parameter.

Save/restore column widths
The class has a Savesettings method to save information about reordered columns and changed column widths. See the Init and Destroy methods of the example form for a way to save and restore these settings.

Column sorting
You can sort on a column by clicking it's header. This only works if it is possible to create an index. So in READ ONLY or EXCLUSIVE OFF situations, columns sorting does not work.

Issues
This version of the class you can actually use. There are however still some issues.

  1. Selecting records with Shift+Dn and Shift+Up eventually 'hangs' the grid control for a while, when you keep these keys pressed. I think there is something wrong with the DOSCROLL method.
  2. Pressing Ctrl+A to select all records in the grid is handled through an ON KEY LABEL. This is, because the Ctrl+A key combination isn't handled by the Keypress event of the grid. The ON KEY LABEL is activated/deactivated in the WHEN and VALID events of the grid. However, when you click on de form itself and than return to the grid, the WHEN event is not triggeredand Ctrl+A isn't (re-)activated.
  3. The dotted outline of the selected row is a VFP shape that does not look like 'the real thing', which has smaller dots. Maybe there is another solution with the use of GDI...
  4. Scrolling records with the vertical scroll bar messes up the screen painting in the grid control.
Visual Foxpro version
The Listgrid class makes use of the AllowSelection property which is introduced in VFP8, so VFP8 or higher is needed.

Download
You can use this class every way you like, but for your own responsibility.
Any positive comments and ideas are welcome at http://hdegroot.blogspot.com/

A download as a ZIP compressed file (44 kb.) is available here.