Class: cCJGrid
Properties | Events | Methods | Index of Classes
Used to create basic (non-data-aware) multi-row, multi-column display and entry grids.
Hierarchy
Library: Windows Application Class Library
Package: cCJGrid.pkg
Description
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](cCJGridColumn.md) 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](cCJGridDataSource.md) class for its datasource object. The cCJGrid object creates this object automatically.
A data-aware version of a grid is provided by the [cDbCJGrid](cDbCJGrid.md) subclass. The cDbCJGrid uses a [cDbCJGridColumn](cDbCJGridColumn.md) class for its column objects and a [cDbCJGridDataSource](cDbCJGridDataSource.md) for its datasource object. A subclass of the cDbCJGrid class, [cDbCJGridPromptList](cDbCJGridPromptList.md), 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 and the Studio
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 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 the 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.
Working with cCJGrids
When working with grids, some of your code (properties, events, methods) is written at the grid object level and some is written at the column object level.
With simple grids, the data from the datasource is loaded in a single step, usually by sending [InitializeData](cCJGrid-Procedure-InitializeData.md) to the grid, passing the data as an array of [tDataSourceRow](../../LanguageReference/tDataSourceRow.md) 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](cCJGridDataSource-Function-DataSource.md) 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
Data Entry
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](cCJGridDataSource-Function-SelectedRow.md). 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 to 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)
ReadOnly Grids
Grids can be used for non-editing purposes such as display and selection. A grid is made non-editable by setting the [pbReadOnly](cCJGrid-Property-pbReadOnly.md) property. You choose to support row selection by setting the [pbSelectionEnable](cCJGrid-Property-pbSelectionEnable.md) property. When grids are read-only, you will often wish to disable column-level focus. This can be disabled with the [pbFocusSubItems](cCJGrid-Property-pbFocusSubItems.md) property.
Multiple-Row Selection Grids
Multiple-row selection is enabled with the [pbMultipleSelection](cCJGrid-Property-pbMultipleSelection.md) property. See that topic for details on working with multiple-row selection grids.
Display Formatting, Hidden Columns, Dynamic Columns, etc.
Numerous other grid features such as display formatting, hidden and dynamic columns, etc., are handled in each individual grid column. See the [cCJGridColumn](cCJGridColumn.md) 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](cCJGrid-Property-phoReportPaintManager.md).
Examples
There are a number of samples of the cCJGrid class, as well as the [cDbCJGrid](cDbCJGrid.md) class, in the Grids.src program in the Specialized Components workspace.