cObject
---cUIObject
------DfComUIObject
---------DfInPlaceComObject
------------DfComActiveXControl
---------------cComActiveXControl
------------------cCJGridControl
---------------------cCJGrid
------------------------cCJGridPromptList
------------------------cDbCJGrid
The cCJGrid class provides the basis for creating multi-row, multi-column display and entry grids.
Each column in a grid is represented by a column object. The cCJGrid uses the cCJGridColumn class for its column objects. These grid column objects, which must be created by the developer, are nested inside of the cCJGrid.
Data is stored and maintained in a datasource object. The cCJGrid uses a cCJGridDataSource class for its datasource object. The cCJGrid object creates this object automatically.
A data-aware version of a grid is provided by the cDbCJGrid subclass. The cDbCJGrid uses a cDbCJGridColumn class for its column objects and a cDbCJGridDataSource for its datasource object. A subclass of the cDbCJGrid class, cDbCJGridPromptList provides support for data-aware lookup lists.
The following provides a short introduction to grids. You should refer to Using Grids for a complete overview of the grid classes. The Class Reference will provide you with syntactical and usage information about the grid classes.
Grids can be created visually within the Studio. To create a grid, you drag a cCJGrid, cDbCJGrid or cDbCJGridPromptList from the Class Palette and drop it onto a container (view, dialog, etc.). New columns are added by dragging column objects (cCJGridColumn, cDbCJGridColumn) onto the appropriate grid object. cDbCJGridColumns may also be also created by selecting and dragging them from the DDO Explorer. When dragged from the DDO Explorer, the grid columns are bound to data (i.e., they are assigned an Entry_Item value).
Columns are moved by dragging them to a new column position. They can be resized by dragging the header column splitter. They can be removed by dragging the column off the grid. When you click on a header, that header will be selected in Code Explorer and in the Properties Panel. Therefore, when you click on a header, you will see the properties for the column and when you click elsewhere in the grid, you will see the properties for the Grid. Those visual properties that make sense to be visually modeled are visually modeled in the Studio.
For further information, see the Visual Designer.
When working with grids, some of your code (properties, events, methods) is written at the grid object level and some is written at to column object level.
With simple grids, the data from the datasource is loaded in a single step, usually by sending InitializeData to the grid, passing the data as an array of tDataSourceRow items. If the grid is changed, the datasource data changes as well.
Object oCustomerGrid is a cCJGrid Set Size to 150 271 Set Location to 13 11 Set peAnchors to anAll Set pbReadOnly to True Set pbSelectionEnable to True Object oCustomer_Customer_Number is a cCJGridColumn Set piWidth to 46 Set psCaption to "Number" Set peDataType to Mask_Numeric_Window Set psMask to "######" End_Object Object oCustomer_Name is a cCJGridColumn Set piWidth to 231 Set psCaption to "Customer Name" End_Object Object oCustomer_Status is a cCJGridColumn Set piWidth to 52 Set psCaption to "Status" Set pbCheckbox to True Set psCheckboxTrue to "Y" Set psCheckboxFalse to "N" End_Object Procedure LoadData tDataSourceRow[] TheData Boolean bFound Integer iRows iNum iName iStatus // Get the datasource indexes of the various columns Get piColumnId of oCustomer_Customer_Number to iNum Get piColumnId of oCustomer_Name to iName Get piColumnId of oCustomer_Status to iStatus // Load all data into the datasource array Clear Customer Find ge Customer by 1 Move (Found) to bFound While (bFound) Move Customer.Customer_Number to TheData[iRows].sValue[iNum] Move Customer.Name to TheData[iRows].sValue[iName] Move Customer.Status to TheData[iRows].sValue[iStatus] Find gt Customer by 1 Move (Found) to bFound Increment iRows Loop // Initialize Grid with new data Send InitializeData TheData Send MovetoFirstRow End_Procedure Procedure Activating Forward Send Activating Send LoadData End_Procedure End_Object
You can then access this data by calling the datasource object's DataSource function, which returns the tDataSourceRow array.
Procedure ProcessGridData Handle hoDataSource tDataSourceRow[] TheData Integer iRows i Get phoDataSource to hoDataSource Get DataSource of hoDataSource to TheData Move (SizeOfArray(TheData)) to iRows For i from 0 to (iRows-1) Send UpdateMyDataRow TheData[i] Loop End_Procedure
All grids are built for data entry. You are allowed to edit data, save rows, delete rows, restore changed rows, insert rows and append rows. Various properties exist which allow you to enable/disable any or all of these features. All grid editing is based around the grid's SelectedRow. If you change rows, you are changing the SelectedRow. Anytime a row changes, any changes in the SelectedRow must be committed, which means it must either be saved or restored back to its original state. The grid will check if the SelectedRow is changed. If it is changed, it must be committed (saved or cleared).
The datasource actually determines what is meant by "save". With a simple datasource, it means that the datasource's array of data is updated. With a data-aware datasource, the save is made to the external data (the database). From a grid's point of view, this is all the same. It performs the same abstract steps. It checks if a save is needed, checks if a save is allowed, allows for a save verification, performs validations on all data and attempts save the data. If this fails, you cannot leave the row.
You may not actually see any of this when you work with a simple grid. By default, there is no verification and no validations and the save is internal to the datasource. Therefore, you just make an edit and move to some other part of the grid. While you may not see it, the entire row-oriented save process does occur. The same sort of thing happens with row deletes, row inserts/appends and row clearing (undo row changes).
In addition to the automatic save of row change behavior, high-level messages exist to perform these grid change tasks. These are assigned to accelerator keys as well: Request_Save (F2), Request_Delete (Shift+F2), Request_InsertRow (Shift+F10), Request_AppendRow (Move to last row and press down arrow), Request_Clear (F5).
Grids can be used for non-editing purposes such as display and selection. A grid is made non-editable by setting the pbReadOnly property. You choose to support row selection by setting the pbSelectionEnable property. When grids are read only, you will often wish to disable column-level focus. This can be disabled with the pbFocusSubItems property.
Multiple-row selection is enabled with the pbMultipleSelection property. See that topic for details on working with multiple-row selection grids.
Numerous other grid features such as display formatting, hidden and dynamic columns, etc., are handled in each individual grid column. See the cCJGridColumn class for more information.
To change display attributes, such as font, of the entire grid, rather than conditionally changing the font of individual cells, use phoReportPaintManager.
There are a number of samples of the cCJGrid class, as well as the cDbCJGrid class, in the Grids.src program in Specialized Components workspace.