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.

4 comments:

Anonymous said...

Thanks it looks and feels great! Can i use this in my application?

Anonymous said...

Hi mircea,

Please do use it in your application!

patrick said...

Thanks for this template... Great article! web application

Archer G. Serpent said...

Hi, thanks for the solution, that is of great help.
A question about the second issue listed... from what I can see, the KeyPress event does handle the Ctrl+A combo. Have I missed something? (For the record: I am not an expert in FoxPro, so excuse me for possibly stupid questions). Thank you again.