Copyright: Copyright (C) 1993-94 Apex Software Corp


TrueGrid Table of Contents

A Data-Aware Grid for Visual Basic 3.0 Data Access

  Overview of TrueGrid

  TrueGrid Pro Features

  How to use TrueGrid's Features, Step-by-step

  Overview of Advanced Topics

  How to Print TrueGrid using Crystal Reports

  Property Reference

  Event Reference

  TrueGrid Properties and Events, Grouped by Functional Area

  Layout Editor Reference

  TGUTILS.BAS:  TrueGrid Utility Functions

  Overview of Sample Code

  Contacting Apex

  Summary of Recent Changes

This is the "Gunsmoke" Version (2.1c) of TrueGrid.

Copyright (c) Apex Software Corporation, 1993-1994.  All rights reserved.


 How to Use TrueGrid

Configuring TrueGrid Database Properties

  Getting started with TrueGrid

  Associating a grid with a Visual Basic Data Control

  How field and column layouts are chosen

  How editing works in TrueGrid

Working with TrueGrid Columns

  Design-time column layouts using the Layout Editor

  Using the Column Properties Dialog

  Adding columns at run time

  Adjusting column properties using Visual Basic code

  Allowing the user to reconfigure grid appearance at runtime

  Using column edit masks

TrueGrid Database Application Techniques

  Using TrueGrid for SQL query results

  Data validation techniques

  Coordinating multiple TrueGrid controls

  Using the BookmarkList to highlight query result rows

How Your Programs Interact with TrueGrid

  How TrueGrid reacts to Dynaset changes

  Data Control interaction and how TrueGrid responds

  TrueGrid live data updates and Validate handlers

  Row numbers and what they mean

  Eliminating unwanted grid refresh

Colors, Fonts, and Configuring the Appearance of TrueGrid

  TrueGrid color settings and font styles

  How to give the grid a 3-dimensional appearance

  Displaying grid lines between rows or columns

  Changing the appearance of the marquee

  Changing colors and fonts for individual columns

Using TrueGrid's Multiple Selection Feature

  Multiple selection overview

  How the user selects multiple rows

  Working with the list of marked rows in your programs

  Clearing marked rows using Visual Basic code

  Using multiple selection in callback (Application) mode

Locked Columns and Introduction to Splits

  Introduction to TrueGrid splits

  Creating locked columns in the Layout Editor

  Creating splits at design and run time

  Choosing to use global or split-specific settings

  User interaction when splits are present

Using Unbound and Calculated Columns

  What are unbound and calculated columns?

  How to use unbound columns

  How to use calculated columns

Using TrueGrid in Callback (Application) mode

  Introduction to TrueGrid callback mode

  Steps to create a callback mode application

  Creating a user-friendly callback program

  Using the CheckRows event

  Displaying graphics in cells

Column Summary Features

  Introduction to Column Summary Features

  Using Column Summaries

Value List Features

  Introduction to Value lists

  Creating a value list using the Field Values Dialog

  Value list validation

  Specifying a Value List default


 Advanced Topics

Realizing the Full Potential of Splits

  Overview of TrueGrid splits

  Global properties versus split-specific properties

  Split groups and unsynchronized splits

  Mouse and keyboard interaction with splits

  Configuring the size of splits

Configuring Splits At Design Time

  Creating splits at design time using the Layout Editor

  Setting split-specific properties at design time

  Using the Layout Editor to configure columns in splits

  How locked columns work by using splits

  Giving the user control over splits

Working With Splits in Your Code

  How your Visual Basic code works with splits

  Creating and configuring new splits

Implementing Drag and Drop using TrueGrid

  Dragging cells or rows from a grid to another control

  Dragging data onto a TrueGrid cell or row

Customizing the Behavior of Cell Editing

  Overview of cell editing

  Customizing the cell text displayed during editing

  Creating a dropdown list instead of editing cell text directly

  Changing cell contents with a single keystroke

  Creating editable calculated and unbound columns

Changing Colors and Fonts on a Per-Cell Basis

  How TrueGrid applies colors and fonts to a cell

  Meaning of cell status values

  Controlling colors and fonts by cell status

  Controlling colors and fonts by cell contents

  Controlling colors and fonts using custom criteria

  Priority of colors and fonts applied to cells

Regular Expressions Reference Material

  Introduction to regular expressions

  Syntax of TrueGrid regular expressions

  Commonly used regular expressions


Contacting Apex

If you have any problems using TrueGrid, or encounter problems which you believe may be software bugs, please contact us and we will do our best to assist you in solving your problem.  For technical questions and support, please use CompuServe or Internet if possible.  We can respond more quickly and effectively on these mediums.  If you don't have either of these, please use fax or telephone as listed below.

CompuServe:	74774,1311	(Tech Support) or

GO APEX

Internet:	truegrid@apexsc.com and

ftp.apexsc.com

BBS:	412-681-4370 (8 data bits /1 stop bit /parity none)

By phone:	412-681-4738

By mail:	Apex Software Corporation

4516 Henry Street

Pittsburgh, PA  15213

By fax:	412-681-4384

Our office hours are 9 a.m. - 6 p.m. (EST)  We are often here after hours, but if not, please leave a message and we will get back to you.


True Grid Overview
 Overview

TrueGrid is a bound database grid for Visual Basic 3.0.  Using technology derived from our Agility database product, TrueGrid manages the interface with the database completely, freeing you to concentrate on important application-specific tasks.

TrueGrid is very easy to use, requiring no more work than simply dropping the grid on a form and setting the DataSource property---that's all!  You don't need to write a single line of code to get the grid up and running, making it ideal for an instant data browser or data display window.

This new version of TrueGrid also adds significant power to the original design.  Full Excel-like split capability, customizable fonts and colors, calculated and unbound columns, and drag-and-drop features are just some of the things which have been added.  Yet, TrueGrid is still very easy to use, and the new features are there only if you want to use them.

The grid works with all formats that Visual Basic recognizes.  Any database that you can use with Visual Basic you can use with the grid.  See Summary of Features for an overview of some of TrueGrid's features.

We've spent a lot of time trying to make TrueGrid the inexpensive alternative for Visual Basic data access users.  We hope you enjoy using it.  If you need technical assistance, please call and talk to us.  We'd be glad to help.

The How to Use TrueGrid section provides detailed examples and instructions on how to use the grid.  If you're already very familiar with Visual Basic and other custom controls, you may want to quickly peruse the Property Listing and Event Listing


Grid Features
 TrueGrid Pro Features

The following is a summary of the major features of TrueGrid Pro:

1.	Easy To Use:  TrueGrid's features are familiar, intuitive, and easy to use.  In most cases, they require no code.

2.	Drop and Go:  Simply drop TrueGrid on a Visual Basic form, set the DataSource property, and instantly you have a fully functional database-aware browse table - without writing a single line of code!

3.	Database Formats:  Supports all database formats Visual Basic recognizes.

4.	No Size Limit:  Automatically handles databases of any size - programmers do not need to adjust any virtual memory settings.  There is no delay or additional memory overhead for large databases.

5.	Fast and Efficient:  Only data required for display will be retrieved, TrueGrid is simply the fastest grid in the market.

6.	Bound Controls:  Automatically works with other Visual Basic bound controls.  All Data Control operations, data validation events, and error trapping are supported seamlessly.

7.	Editing and Data Validation:  In-cell editing with automatic update and data validation events.

8.	DropDown Text Edit:  A multi-line text control will dropdown automatically when editing large data.

9.	Configurability:  Most properties are configurable at both design time and by code.  In addition, splits, column width and column order are configurable interactively by end-users at run time.

10.	Layout Editor:  Allows programmers to visually and interactively configure various column and split properties at design time.  Features such as locked columns are automated.  TrueGrid is the only grid that allows the programmer to visually configure the appearance of the grid at design time.

11.	Tab and Arrow Keys:  Complete control of the use of the tab and arrow keys to navigate through the cells of the grid or to move focus to another control.

12.	AddNew:  Allow end-users to enter a new record at the bottom of the grid with automatic update and error trapping.

13.	Select and Mark:  Select and mark non-contiguous records by mouse clicks, or by code.

14.	Callback: TrueGrid can be used with data managed by programmers; it doesn't have to be bound to a Data Control.

15.	EditMask:  The EditMask property fully supports the Visual Basic Format$ string.

16.	Cross-Form Binding:  TrueGrid Pro can be bound to a Visual Basic Data Control in another form.

17.	Splits:  Splits a grid into any number of independent grids.  The splits can scroll simultaneously or independently, or be locked from scrolling.  An Excel-like split bar allows end-users to create splits interactively.  Programmer can decide how much interactive control the end-users have.

18.	Per-Cell Color and Font:  Control the color and font style of each individual cell based on cell contents and cell status.  If cell contents or status are updated, the color and font will be adjusted automatically.

19.	Indentation:  Control per-cell text indentation, ideal for building outlines and subtitles in a grid column.

20.	Multi-Line Row and Heading:  Heading and row heights are independently controlled.

21.	Drop Down Combo or List Box:  Easy to program features to drop down a combo or list box, or even any Visual Basic control from a cell.

22.	Drag and Drop:  Easy to program features to allow drag and drop of data to and from other controls.

23.	Calculated Columns:  Create columns to display calculated expressions simply by entering a Visual Basic expression in a ColumnExpression property.  No code required.  Visual Basic constants (e.g., null, True, False, date constants, etc.), operators, field names, functions (over 35 Visual Basic functions are supported), and even other calculated columns are supported.  TrueGrid automatically resolves all dependencies and calculation orders.

24.	Cell Graphic:  You can display graphical images in a cell, not just textual information.

25.	In-Cell Combo Box and Radio-Button:  For easy data entry and inspection; eliminate end-user typing and error.

26.	Value List:  Values from bound or calculated columns can be translated to any textual strings or pictures for display purposes.  For example, (0, 1) may be displayed as (Yes, No), country names may be displayed as bitmaps of their respective flags.  Value lists can be defined at design time using the Layout Editor - no code necessary!

27.	Column Sums:  Built-in properties to calculate and maintain field column sums.

28.	Complete Programmer Control:  Programmer can override all default and inherited data and attributes and dictate what data, color, and font styles the grid should display in a cell using the UnboundFetch and FetchAttribute events.

29.	Royalty Free:  TRUEGRID.VBX can be distributed free with your runtime applications.

30.	On-Line Help:  Context sensitive help with detailed overview, property and event references, and plenty of examples.

31.	Samples:  TrueGrid Pro comes with plenty of sample applications to illustrate product features.  They also provide useful tips and tricks.

32.	Built-in Crystal Reports support:  You can perfrom ad-hoc SQL queries, display and edit the result (dynaset) data on TrueGrid, configure the grid (hide, resize or rearrange field columns) at runtime or design time, and generate reports on the fly.


Configuring TrueGrid Database Properties

 Getting started with TrueGrid

 Associating a grid with a Visual Basic Data Control

 How field and column layouts are chosen

  How editing works in TrueGrid

Getting started with TrueGrid

If you are unfamilar with how to add a VBX to your project or you are just getting started with Visual Basic the following steps should help you get started with using TrueGrid.  If you are familar with using VBX's then you probably can skip this section.

TrueGrid is just like any other control that you use in the Visual Basic toolbox.  To add TrueGrid to your toolbox do the following:

1.	Choose Add File... from the Visual Basic File Menu option.

2.	In the File Dialog go to your Windows\System directory.

3.	Find the file truegrid.vbx and choose OK.

You should now have the TrueGrid icon ( [image] ) in your toolbox.  You can now use TrueGrid just like any other object in the toolbox.  Click on it, move the crosshair mousepointer to a location on the form, and draw the grid. You can also double click on the TrueGrid tool to place a presized grid on the form which you can then move and resize.

If you want TrueGrid to always show up in your toolbox you can do the following:

1.	Choose Open Project... from the Visual Basic File Menu option.

2.	In the File Dialog go to your Visual Basic installation directory.

3.	Find the file autoload.mak and choose OK.

4.	Repeat steps 1-3 for adding TrueGrid to your project.

5.	Choose Save Project from the Visual Basic File Menu option.

TrueGrid will now automatically be added to all future projects.

Associating a grid with a Visual Basic Data Control

You can make an association between a TrueGrid data bound control and a Visual Basic Data Control by setting the DataSource property of the grid after the Data Control has been created on the same form.  This is all you need to do to make TrueGrid fully aware of the database in your application.

Once such a link exists, TrueGrid respects the information present in the Data Control to simplify further refinement of your application:

*	Once the grid has been associated with a Data Control, you can click on the Layout property and TrueGrid will ask whether you want to use the field layout of the database automatically.

*	When you run you application, TrueGrid will automatically respond by displaying the contents of the database opened by the Data Control.  Data will be fully available at runtime, and can be edited as well.

Any changes you make to the Data Control will be automatically sensed by TrueGrid and it will update its display accordingly.  However, TrueGrid waits until the system is idle before performing such display updates, since programs may want to perform many actions before it is necessary to synchronize the display.

How field and column layouts are chosen

In a TrueGrid display, each column represents a single field of data.  For each column, the grid needs to know the fieldname associated with the data, and optionally a heading to be displayed above the data column.

TrueGrid gets information about field names and headings in one of three ways:

1.	At design time, you can select the Layout editor to specify column information manually.

2.	At design time, when you attempt to use the Layout editor for the first time, TrueGrid asks if you want to use the field definitions in the database rather than defining them yourself.  This makes the initial layout simple to create, and you can easily modify it with further use of the Layout Editor.

3.	If you don't define a layout at design time at all, TrueGrid will automatically create one based upon the database used when you run your program.  This mode is the most automatic of all and is quite acceptable for most quick applications.

At run time, you can perform database actions which may alter the layout needed to display the data.  For example:

1.	You may change the Database or Connect strings in the Data Control, which results in a different database.

2.	You may change the RecordSource property of the Data Control (for example, to invoke an SQL query).

In all such cases, the grid will automatically sense the new column layout and reconfigure itself.  But, if you defined a design-time layout yourself, the grid won't change the layout at all, assuming that you want total control of the grid's appearance.

How editing works in TrueGrid

TrueGrid is a fully editable grid control.  When the grid is in editing mode the cell will switch to the EditForeColor and EditBackColor that you have specified.  By default these colors will be set to the Windows Highlight and Highlight Text colors.  Note that if you do use the default colors you will not be able to see text you have highlighted by dragging the mouse.  To correct this simply change the EditForeColor and EditBackColor to different values.

The grid can enable editing in one of two ways.  In the first case, you simply click on a cell and begin typing.  In this case the grid will overwrite the previous value of the cell with the key(s) you type.  If on the other hand you wanted to modify the existing value in the cell, just click on the current cell with the mouse.  The grid will switch to insert mode and you can then position the cursor to the place in the text you want to modify.

The editing cell follows the standard behavior of a Visual Basic text controls including navigation, selection, and special keys.  If the text in the cell exceeds the width of the cell then a special edit dropdown will appear.  This cell will expand within the column until it reaches the bottom of the grid.  You can navigate within the special cell just as you would any mutli-line text control.  If the field is a memo field then the cell will dropdown with a vertical scroll bar to allow you to easily navigate through the field.


Working with TrueGrid Columns

  Design-time column layouts using the Layout Editor

  Using the Column Properties Dialog

  Adding columns at run time

  Adjusting column properties using Visual Basic code

  Allowing the user to reconfigure grid appearance at runtime

  Using column edit masks

Design-time Column Layouts using the Layout Editor

The Layout Editor can be used at design time by clicking on the Layout property.  Alternately, you can click with the right mouse button over a specific grid to make the Layout Editor appear.  Each grid has its own layout of columns, and the Layout Editor can be used to add, remove, and modify the column layout.  All of the layout information is saved as part of your Visual Basic project, so it will be used at runtime automatically.

If your grid is associated with a database, then you will be prompted to find out if you want to use the field layout of the database for your initial column layout.  If you say No, then you can design your column layout from scratch anyway you wish.

The Layout Editor shows a copy of the grid control in a dialog, with a special menu which can be popped up using the right mouse button:

The pop-up menu controls settings for only a single column---the column you clicked over.  For the Heading Text, Field Name, and Edit Mask properties, choosing an item allows you to edit the respective text.  All text editing occurs inside the heading area for the given column, although the text normally displayed there is the Heading Text item.  See the Layout Editor for a complete description of how this editor works.

Using the Column Properties Dialog

The Column Properties Dialog allows you more control over the layout of TrueGrid.  You can bring up the Column Properties Dialog by clicking on the 'Properties...' option in the Layout Editor pop-up menu.

The number at the upper left indicates the current column.  You can move from column to column using the scrollbar at the left.  The grid in the Layout Editor will automatically scroll the column into view if it isn't already visible.  Below that are three radio buttons that indicate the type of column: bound, unbound, or calculated.  When you first attach a database to the grid and use the default layout, the columns should all default to Bound.

The heading text shows the current value of the column heading.  The width shows the width of the column in characters.  The limit value is either zero (meaning that there is no data entry limit), or the maximum number of characters the user is allowed to type in the field.  The edit mask specifies a standard Visual Basic Format$ string which controls the display of data in the column.  A set of standard format masks is provided in the dropdown, or you may type your own format mask directly into the text box.

For bound columns, the Field Name must be set to a valid field for the database to which the grid is bound.  If TrueGrid is currently bound to a valid Data Control, the dropdown will contain a list of the valid fieldnames.  Note, however, that you can type any fieldname here, since TrueGrid assumes that the database may be different when your application runs.  For calculated columns, the Expression must be set to a valid Visual Basic expression (see the ColumnExpression property) which is used to calculate the value of the column at runtime.

The two frames in the upper right-hand corner allow you to set the justification and fontstyle for the Heading and the Column text.  The checkboxes are normally greyed, indicating that the fonts used for the headings and text are the default grid fonts.  Checking these boxes will override these settings for the current column.

If you want to quickly setup the current column(s) to be locked on the left-hand side of the grid then you can just click the 'Locked at left' checkbox.  For more on this see Creating locked columns in the Layout Editor.

The last two checkboxes allow you to toggle the column's visibility and editability.  When you exit the Layout Editor, any invisible columns are physically removed from the design-time layout automatically.  However, columns which are made invisible at run time (using the ColumnVisible property) remain as part of the grid's column layout.

The buttons on the bottom of the dialog allow you to add a new column, delete a column, and update the current column.  The update allows you to verify your changes before leaving the Column Properties Dialog.  Clicking OK will also update the current column upon exiting.

The scrollbar on the left allows you to change from column to column with the Column Properties Dialog.  Changing columns automatically saves the changes of the previous column.  Clicking the Cancel or OK buttons will only affect the current column and not any of the previous columns.

See Column Properties Dialog for a complete reference for this dialog box.

Adding Columns at Run Time

Using grid properties and Visual Basic code, you can add columns to the grid at runtime.  You can even perform complete grid configuration yourself, rather than using the interactive tools.

Here is an example of how a column can be added to the grid at runtime:

nextc% = Table1.Columns + 1 ' index of next column

' add a column with new properties

Table1.ColumnField(nextc%) = "firstname"

Table1.ColumnName(nextc%) = "First Name"

Table1.ColumnWidth(nextc%) = 25

Note that simply assigning to one of the column properties with a column number one greater than the final column will automatically add a new column.  (Note that just after the first assignment, Table1.Columns returns the new, higher value).

Once added, the new column will be automatically linked to the DataSource database, if one is opened.

You cannot remove columns invidually, but you can hide them (using the ColumnVisible) property.  You can also remove all of the columns from the grid layout with the following line of code:

Table1.Columns = 0

Adjusting Column Properties using Visual Basic Code

Existing column properties can be changed at runtime using Visual Basic code.  For example, changing ColumnField can be done as follows:

Table1.ColumnField(3) = "DateofBirth"

When this statement is executed, the grid will automatically refresh any data in column 3 by refreshing it from the database.  Thus, such changes will be reflected automatically by the grid.

Here are the column properties you may wish to change:

ColumnBackColor	The background color for the column.

ColumnField	The field name associated with the specified column.

ColumnForeColor	The foreground color for the column.

ColumnName	The heading for the specified column.

ColumnSize	The maximum data entry width, in characters.

ColumnStyle	The column justification and editability bits.

ColumnVisible	The column's visibility state.

ColumnWidth	The display width, in characters of the grid's font.

EditMask	The edit mask for the column.

Changing any of the above properties causes the grid to respond by updating its display to reflect the change.

Allowing the User to Reconfigure Grid Appearance at Runtime

If the Configurable property is True (which is the default), then TrueGrid allows the user to interactively move and adjust the column layout at runtime.

All user adjustment is made with the mouse, as follows:

1.	If VertLines is set so that vertical column separators are visible, then a special "move line" cursor will appear when the user has the mouse positioned over a vertical line.  In such cases, the user may grab the separator and drag it to the left or right, thereby enlarging or shrinking the column immediately to the left of the line.

2.	If Headings is true, making grid column headings visible, then the user may hold down the mouse over a column heading.  The entire column becomes highlighted and it can be dragged to the left or right to change the column ordering.  Note that this does not change the indexes used in your program to refer to columns in the grid.  No matter where the user moves the leftmost column, it will remain column 1 to your program.  (The ColumnOrder property, which designates the visual order of columns, is used to rearrange columns without affecting their index number.)

3.	Columns may be shrunk to nothing (using the technique in item 1), in which case the ColumnVisible property for the column is set to False, although the column is not physically removed from the grid.

If the grid is not configurable (the Configurable property is set to False), then no user configuration will be permitted and all mouse events are passed to standard event handlers such as MouseDown.

Using Column Edit Masks

Each column has an optional edit mask associated with it.  The edit mask can be set in three ways:

1.	The EditMask menu item can be selected from the Layout Editor at design time to set an edit mask for the column.

2.	At run time, the EditMask property can be set in Visual Basic code to specify an edit mask for the column.  The column will automatically be refreshed to reflect the newly formatted appearance of the columns.

3.	In the Column Properties Dialog you can set the edit mask by putting one in the Format$ text box.

Edit masks in TrueGrid are the standard Visual Basic Format Strings used in the Format$ function.

The edit mask is used only for the display of data in the grid.  When a cell is opened for editing, the actual underlying data is displayed, rather than the formatted value.  When editing is complete, TrueGrid displays the changed data in red until database motion or an Update method causes the data to be written back to the database.  This tells the user that the data has been changed, but still hasn't been updated.


TrueGrid Database Application Techniques

  Using TrueGrid for SQL query results

  Data validation techniques

  Coordinating multiple TrueGrid controls

  Using the BookmarkList to highlight query result rows

Using TrueGrid for SQL Query Results

One important use for TrueGrid's ability to automatically sense changes to the database at runtime is for displaying the results of ad-hoc SQL queries.

For example, assume that a grid is connected to the Data Control, Data1, and that a query button is provided which contains code similar to this:

Sub QueryButton_Click ()

' Copy SQL query to RecordSource

Data1.RecordSource = QueryText.Text

' Refresh data set ... connected grid will respond

' automatically

Data1.Refresh

End Sub

This simple example illustrates two important points:

1.	No code is necessary to tell the grid what to do.  The change to the RecordSource property will be detected by the grid and it will display the new query result automatically.

2.	The grid will automatically change its field layout to match the new configuration of the query result.  This can be important if the query uses aggregate functions (such as count()) or specifies alternate field lists or calculated fields.

The second point is especially interesting.  Imagine an SQL query such as this:

SELECT COUNT(*) FROM EMP

The above query returns a single row, containing a single value which is the number of rows in the database EMP.  The grid will display the result like this:

Notice that a single column is displayed (called "Calc#0" since no name was given to the result field) and a single query row containing the count result (641) is displayed.

Similarly, you can select only some fields in a query, such as the following:

SELECT FIRST, LAST, TITLE FROM EMP WHERE ZIP >= 90000

The above query will select only three fields, but contingent upon a zip code condition.  The result looks like this:

Notice how the field headings have been reconfigured automatically to reflect the new column layout.  The grid will also respond to queries which have expressions instead of simple field names:

SELECT FIRST, UCASE(LAST), TITLE FROM EMP WHERE ZIP >= 90000

Now, the query result includes a calculated column instead, which reflects the result of changing the last name field to upper case:

You can also give calculated columns names by including an "AS" clause in your SQL statement:

SELECT FIRST, UCASE(LAST) AS UPPERLAST

FROM EMP WHERE ZIP >= 90000

In this case, the query result table will include the name of the calculated column:

Whether giving users access to SQL statements directly, or using these features in your program, TrueGrid provides a powerful mechanism for direct display of SQL queries.  Since TrueGrid configures itself automatically, very little programming is necessary to create an extremely powerful user interface.

Data Validation Techniques

TrueGrid includes protocols for several data validation techniques.  When data is updated directly using the grid, a special protocol is followed:

1.	When a cell is opened for editing, the user can make changes directly to the data in the grid.  When completed, the grid Validate event is triggered.  This gives you the immediate opportunity to reject or accept data as it is being entered.  If validation doesn't fail, the grid Update event is triggered, indicating that data has been successfully updated by the user.  This does not indicate that the data has been written to the database ... only that the user has changed the visible data in the grid.

The grid Validate and Update events are useful for providing the user with immediate feedback about the data they have entered.

2.	Changed data is held in the grid until it is updated to the database, no matter how many changes are made to the current row.  Data is updated to the database when (1) the record pointer is moved for any reason, (2) when an UpdateRecord method is sent to the Data Control associated with the grid.

Two grid properties, ColumnChanged and ColumnText are used to determine what data in the current row has been modified by the user.  Of course, you can determine this directly by putting code in the grid Validate and Update handlers, but it is often easier to rely on the grids bookkeeping and check all of the data later.

The ColumnChanged property returns True if data in the specified column has been changed by the user, but not yet updated to the database (it appears in red in such circumstances).  The ColumnText property returns the text of the specified column cell.  The text will be the edited text if ColumnChanged is True and will be the database text if ColumnChanged is False for that column.

For example, in the Data Control Validate handler, you could examine all of the columns in the grid to determine if all of the changes are valid:

' Check all grid data which has been changed

For i% = 1 To Table1.Columns

If Table1.ColumnChanged(i%) Then

ValidateData i%, Table1.ColumnText(i%)

End If

Next i%

When data is successfully updated, all of the ColumnChanged values are set to False (as is the DataChanged property for the grid, which reflects the overall change state of the grid).

Coordinating Multiple TrueGrid Controls

You can link multiple TrueGrid controls together by using the RowChange event to trigger related actions.

Whenever the highlighted row moves in the grid, the RowChange event is sent, indicating that a new row has become current.  RowChange is triggered in the following cases:

1.	If the user clicks on a new row in the grid.

2.	If program code moves the record pointer (using methods like MoveFirst, MoveNext, FindNext, etc.).

3.	If the data in the grid is refreshed.

4.	If the user moves the record pointer using the navigation buttons on the Data Control associated with the grid.

The RowChange handler is a convenient place to coordinate activities with other controls or databases.

For example, assume that you have one grid (CustTable) containing customers and another (CustInvTable) containing invoices for the customer.  CustTable is linked to Data Control CustData and CustInvTable is linked to Data Control CustInvData.  You could use the RowChange handler in CustTable to perform an SQL selection so that invoices are always displayed as new customers are selected:

Sub CustTable_RowChange ()

' Get the customer number for the new row

custid$ = CustData.RecordSet("CustNum")

' Build a query for the invoice database

 Note: if the field type is a string the variable is surrounded by single quotes

cquery$ = "SELECT * FROM CUSTINV WHERE CUSTNUM = " & custid$ &

' Invoke the query, which causes the second grid to update

' automatically.

CustInvData.RecordSource = cquery$

CustInvData.Refresh

End Sub

Again, note that no special handling is required for the grids associated with the Data Controls.  They respond automatically to changes made by such code.

Using the BookmarkList to Highlight Rows

TrueGrid has a powerful multi-row selection feature which relies on bookmarks.  One or more grid rows can be selected (and are displayed differently using the SelectedForeColor and SelectedBackColor).

The grid maintains a list of all selected rows in the BookmarkList property.  Here's how BookmarkList behaves:

1.	The user can select a row by moving the cursor to the leftmost area of the grid and clicking.  When this happens, the grid automatically adds the newly selected row to the BookmarkList and updates BookmarkCount.  The opposite happens when a user deselects a selected row.  (The SelectMode property has to be set so that this is enabled.)

2.	You can examine the contents of BookmarkList at any time to find out which rows are selected.

3.	You can set an element of BookmarkList to an empty string ("") to remove the bookmark at that position.  The selected row will no longer be highlighted and BookmarkCount will automatically be decremented.  (TrueGrid will renumber all of the subsequent bookmarks to fill the empty slot in the BookmarkList property array.)

4.	You can add bookmarks to the bookmark list yourself by adding them at the end.  The grid will automatically highlight any visible rows which correspond to your new bookmarks.

5.	By setting BookmarkCount to zero (0), you can clear the entire selection.

This facility is extremely powerful.  For example, you could highlight all rows in the grid containing employees who have the title "Manager" with the following simple subroutine:

Sub HighlightManagers()

' Set criteria for FindFirst/FindNext

criteria$ = "TITLE = " + chr$(34) + "Manager" + chr$(34)

' Loop through, adding each manager to the BookmarkList

Data1.RecordSet.FindFirst criteria$

While Not Data1.RecordSet.NoMatch

Table1.BookmarkList(Table1.BookmarkCount) = Data1.RecordSet.Bookmark

Data1.RecordSet.FindNext criteria$

Wend

End Sub

When the above loop is complete, all of the bookmarked rows will automatically be highlighted in the grid and the user can view the results.

You can also move the pointer to one of the current bookmarks:

Data1.RecordSet.Bookmark = Table1.BookmarkList(0)

This moves the record pointer (and the grid highlighting) to the first selected row.


How Your Programs Interact with TrueGrid

  How TrueGrid reacts to Dynaset changes

  Data Control interaction and how TrueGrid responds

  TrueGrid live data updates and Validate handlers

  Row numbers and what they mean

  Eliminating unwanted grid refresh

How TrueGrid Reacts to Dynaset changes

When you link a grid to a Data Control, you are actually linking the grid to the underlying Dynaset which is managed by the Data Control.  The Dynaset can be accessed directly by using the RecordSet property of the Data Control:

Data1.RecordSet.MoveFirst

The above line positions the record pointer of the Dynaset to the first record in the record set.

You needn't worry about keeping the grid synchronized with changes made to the Dynaset.  This happens automatically.  In fact, modifying the Dynaset is the preferred way to affect changes to the grid display.

Here is how the grid responds to various operations performed on the Dynaset associated with the Data Control:

MoveFirst, MoveNext, MoveLast, MovePrevious
The grid will move its highlight in response to these methods when they are invoked on the Dynaset.  The grid optimizes its response to these messages.  Thus, if your code performs a MoveFirst followed by 20 MoveNext methods, the grid will position to row 21 only once.  If possible, the grid will adjust its row numbering scheme and scroll bar to reflect the new position within the database.

FindFirst, FindNext, FindLast, FindPrevious
The grid will move its higlight in response to a new row becoming current after these methods are invoked on the Dynaset.  However, the grid may not know what actual row number the new row possesses.  For example, FindNext may move an unspecified number of rows forward and there is no way to determine how many.  To avoid time-consuming counting operations, the grid simply uses a "fictitious" row number until it gains more information about how many rows precede or follow the new row.  For the user, this behavior is usually undetectable, but results in vast increases in speed over alternative techniques.

AddNew	When AddNew is executed, TrueGrid displays a blank row one row after the last row of data (or in the first row, if the database is empty).  If no data is entered in the row, TrueGrid removes the row when another row is selected.  However, if data is typed into the new row, TrueGrid will cause a new record to be added to the database whenever movement occurs off the row, or the Recordset Update event is executed.  This behavior only occurs if AddNew is the last command executed before the grid begins waiting for user input.

Update	The update event causes the grid to instantly write any changed data to the database (providing that the Data Control Validate handler did not suppress the operation).  Any edited cells will be unhighlighted to indicate that the data has now been written.

Refresh	Refreshing the Dynaset causes the grid to redisplay all rows of data, and analyze the field structure of the result set to see if it has changed.  Any changes to headings or field names will be automatically made, unless there is a design-time layout defined using the Layout property.

The Data Control itself also supports several methods which affect the way the grid reacts to data changes:

UpdateRecord
The data in the grid will be written automatically to the database.

UpdateControls
This method causes any changed data in the grid to be refreshed from the database.  Thus, any editing done by the user is lost and the original field data will be displayed once more.

Data Control Interaction and How TrueGrid Responds

The Data Control panel can be used to navigate through any grids connected to it.  Each of the buttons performs its respective function and the row change is indicated in the grid:

*	Pressing the "move to beginning" button has the same effect as a MoveFirst method sent to the Dynaset.  The grid will position to the first row in the set.

*	Pressing the "move to last" button has the same effect as a MoveLast method sent to the Dynaset.  The grid will position to the last row in the set.

*	The "move to next" and "move to previous" buttons have the same effect as MoveNext and MovePrevious when sent to the Dynaset.  The grid will move the highlight forward or backward by one row.

If you depress the Data Control buttons rapidly, the grid may have to "catch up" but will eventually resynchronize with the new position.

If grid data has been edited, then moving the pointer using the Data Control will automatically trigger an update.

TrueGrid Live Data Updates and Validate Handlers

Data in the grid can be updated directly, and validate handlers in both the grid and in the Data Control can be used to control the outcome of the update.  Some details about how grid editing occurs:

1.	When a cell is opened for editing, the user can make changes directly to the data in the grid.  When completed, the grid Validate event is triggered.  If validation doesn't fail, the grid Update event is triggered, indicating that data has been successfully modified by the user.

2.	Changed data is held in the grid until it is updated to the database, no matter how many changes are made to the current row.  Data is updated to the database when (1) the record pointer is moved for any reason, (2) when an UpdateRecord method is sent to the Data Control associated with the grid.

Two grid properties, ColumnChanged and ColumnText are used to determine what data in the current row has been modified by the user.  The ColumnChanged property returns True if data in the specified column has been changed by the user, but not yet updated to the database (it appears in red in such circumstances).  The ColumnText property returns the text of the specified column cell.

TrueGrid uses bookmarks internally to navigate through the database.  Thus, whenever a Data Control's Validate handler is called in response to grid movement, the DATA_ACTIONBOOKMARK action will indicate that movement is about to occur.  In your validate handler, you have the following options:

1.	You can cancel the movement, by setting the Action parameter to 0.  In such a case, the grid will return the highlight to the original row rather than the newly selected row.  If you set the Save parameter to False, then any user edits will remain and the user will need to change something before continuing.  This is (typically) how invalid data is handled.

2.	You can allow the movement to continue, but ignore any changes made by the grid.  You can do this by setting the grids DataChanged property to False, which causes the grid to eliminate any user edits it is currently displaying.

Avoid setting the Action parameter to any other value, since the grid behavior may not be as you expect (although the grid will properly handle such changes).  For example, if you inadvertently set Action to DATA_ACTIONMOVEFIRST, then any attempt to change to another row will force the grid back to the first row.

Row Numbers and What They Mean

TrueGrid uses row numbers to identify rows in the grid, but in general, these row numbers are meaningless except for some programming purposes.  This section explains why this is so.

First, Visual Basic databases and sets do not have row numbers at all.  You can move to a particular row by moving to the first or last record, then counting from there.  If you are at a particular row, it can be quite time consuming to determine what row you are at.  For example, if you are at an unknown row, you could remember its bookmark, then go to the first row, counting forward until you reach the bookmarked row.

This works well for very small databases, but for larger databases, such determinations can take minutes (or even hours).  This is a limitation (or rather a feature, actually) of Visual Basic's data access system and cannot be avoided.

TrueGrid was designed with efficiency as its primary concern.  Thus, although knowing exactly what row you are at can be convenient for the programmer, it is disasterous in terms of overhead.  Thus, the grid operates in one of three different modes, and it does so transparently to the user:

1.	Neither the first nor last row number is known.  This situation occurs more often than you think.  For example, imagine that a FindNext command has moved to a record somewhere in a 400000 record database.  There is no way to determine whether you are at row 3000 or 300000, and finding out could take 20 minutes of searching.  To avoid this, the grid simply assumes that there may be an unknown number of rows before and after the new row.  In such cases it makes up a fictitious row number (usually 500000) and displays records near the current record.  The display thus occurs instantly, and as you move forward or backward, the grid moves relative to the fictious position until it actually hits the beginning or end of the set.  In the latter case, it updates its information so that either the first or last row number are now known, and starts using real row numbers.

All of this is transparent and leads to very rapid operation.  One side effect is that the scroll bars are sometimes approximate.  In the above case, the scroll bar would be positioned roughly in the middle, since the grid doesn't know where in the database you are actually positioned.

2.	The last row number is unknown.  This is the usual cirumstance when browsing a new set which is too large to display.  Rather than try to determine how many rows there are in the set, TrueGrid assumes that there may be an infinite number of rows, and displays only those necessary.  As you move forward, the grid will detect the last row when encountered and update its internal information about the size of the set.

In this case, the scroll bar moves more slowly as you move further down in the database, since the grid doesn't really know how many records there may be.  Once the total number of rows is known, the scroll bar will behave in a linear fashion.

3.	First and last row number are known.  In this case, the grid's Rows and RowIndex properties accurately reflect the actual row within the set.  The grid's scrollbar will be very accurate as well.  The grid knows you are at the first row when you do a MoveFirst, and knows the last row when you do a MoveLast.  Both of these operations (as well as scrolling to the first or last record) will cause the grid to sense the actual row position of the data.

Once you are aware of these factors, you can more readily understand and use the values of the Rows and RowIndex properties.

RowIndex can always be used to position to the first row:

Table1.RowIndex = 1

If the grid doesn't know where the first row is, it will find it in order to satisfy your request.  Similarly, you can always position to the last row:

Table1.RowIndex = Table1.Rows

Again, the grid will determine the total number of rows in order to position to the last row properly.  You can also cause such positioning by sending the MoveFirst or MoveLast method to the corresponding Dynaset associated with the grid.

So long as the grid doesn't change from one "mode" to another, you can use the RowIndex to move the highlight relative to visible locations in the grid.  For example, you can move the highlight to the first row visible in the grid:

Table1.RowIndex = Table1.TopRow

or the last on the screen:

Table1.RowIndex = Table1.BottomRow

You can move the highlight forward or backward:

Table1.RowIndex = Table1.RowIndex + 1

Table1.RowIndex = Table1.RowIndex - 1

Setting RowIndex is not the recommended way to move the record pointer, although it will work.  It is best to manipulate the Dynaset directly using methods such as MoveFirst, MoveNext.  Setting RowIndex is useful only for special cases.

Eliminating Unwanted Grid Refresh

Normally, TrueGrid is very intellegent about deferring screen updates until it is absolutely necessary.  You should rarely need to worry about the grid's operation, and simply write code which works directly with the database.

How does the grid sense that it may refresh?  It waits until you enter the Windows idle loop.  This generally occurs when your code stops executing and the system is waiting for user input.  You can force the grid to think the idle loop has been entered by executing a Visual Basic DoEvents call, which causes all controls to become active.

In some circumstances, you may want the grid to remain "frozen" as it is and not respond to any database changes you make.  To do this, set the grid's Active property to False temporarily while you perform whatever action is necessary, then set it to True again when you want it to resynchronize with the database.  Although you should rarely have to do this, one situation which demands this is the use of a modal form which pops up while the database is in an uncertain state.  If you don't set Active to False, then the grid will update to reflect the new database state.  If you want to avoid this while processing a modal dialog, deactivate the grid when your dialog is displayed, and reactivate it when the dialog is complete.

It is dangerous to leave the grid Active property set to False for any longer than necessary.  When the Active property is False, the database position and the grid position are permitted to diverge.  This can cause confusion for the user.  For example, the highlighted row may not be the current row at all, and attempts to edit the data in the grid may edit the wrong row.


Configuring the Color and Appearance of TrueGrid
Colors, Fonts, and Configuring the Appearance of TrueGrid

  TrueGrid color settings and font styles

  How to give the grid a 3-dimensional appearance

  Displaying grid lines between rows or columns

  Changing the appearance of the marquee

  Changing colors and fonts for individual columns

TrueGrid Color Settings and Font Styles

TrueGrid supports a wide variety of color settings to assist you in customizing the appearance of the grid.

Here are some of the colors you can change, and why you might want to change them:

EditBackColor, EditForeColor
When a cell is opened for editing, it is changed to this color.  By default, the system highlight colors are used, but this can make it difficult to see the text selection of the edited text.

ForeColor, BackColor
These colors specify the foreground and background color for the entire grid and normal displayed text.  For 3D effects, BackColor must be set to light grey.

HeadBackColor, HeadForeColor
These colors are used for the heading area of the grid (providing that the Headings property is True).  These colors are used only when the grid has focus.  When the grid doesn't have focus, the InactiveForeColor and InactiveBackColor are used for the headings.

HeadFontStyle
This property specifies the font style used for the heading area, if different from the fonts used for the overall grid.

InactiveBackColor, InactiveForeColor
These colors are used for the heading area of the grid when it doesn't have focus.

SelectedBackColor, SelectedForeColor
These colors are used for the display of rows which have been selected by the user, or which are selected because their bookmarks have been added to the BookmarkList property.

VertColor, HorzColor
These colors are used in conjunction with the HorzLines and VertLines properties to specify the color of the grid separator lines.  For a 3D appearance, these colors should be set to dark grey and the HorzLines and VertLines property should be set for 3D line appearance.

How to Give the Grid a 3-Dimensional Appearance

TrueGrid supports both a standard, "flat" control appearance and the more attractive 3D appearance used by many controls.  By default, the grid appears as a standard, non-3D control.  However, you can achieve a 3D appearance by setting the following properties at design-time:

1.	Set both the HorzLines and VertLines properties to "3D" (integer value=2).

2.	Set the BackColor property to light grey.

3.	Set the HorzColor and VertColor properties to dark grey.

That's all there is to it.  The grid will display cells using a 3D appearance, and the marquee will display a raised current cell when it is set to value 4 (Highlight Row and Cell).

You can achieve a 3D effect using other color combinations, but you will need to experiment.  For example, a rather offensive 3D display can be concocted using light and dark yellow instead of grey in the above examples.  In our experience, grey remains the best.

Displaying Grid Lines Between Rows or Columns

The HorzLines and VertLines properties allow you to choose whether horizontal and vertical lines are used in the grid.  Both are optional, and each have three values:

0 -	None.  No lines are displayed in the given direction.

1 -	Single.  A single-width line is displayed using the color specified by HorzColor or VertColor.

2 -	3D.  3-dimensional lines are used.  In this case, HorzColor and VertColor specify the darker edge of the 3D bevel and the grid interpolates to find a lighter color for the opposite size of the bevel.

Lines cause slightly less data to be displayed in the grid, since they take up space.  You may want to experiment with different settings to find out what is appealing to you.

Changing the Appearance of the Marquee

The marquee is the name of the higlighted area which represents the current cell or row of the grid.  The MarqueeStyle property can be set to have 5 possible presentations, illustrated below.

MarqueeStyle = 0 - Dotted Cell Border

This is the default appearance of the marquee:

MarqueeStyle = 1 - Solid Cell Border

This is a more distinctive form of cell highlighting, often useful when a different background color is used (since the dotted rectangle is often difficult to spot):

MarqueeStyle = 2 - Highlight Cell

This style inverts the current cell completely, making it very visible.  Values of EditBackColor and EditForeColor should be chosen carefully to make a pleasing effect if your grid is editable:

MarqueeStyle = 3 - Highlight Row

The entire row will be highlighted, but it won't be possible to tell which cell is the current cell in the row:

MarqueeStyle = 4 - Highlight Row & Cell

This value should only be used if 3D lines are used in the grid, since cell highlighting is accomplished using a "raised" appearance for the current cell:

MarqueeStyle = 5 - None

This setting will make the marquee disappear completely.  Often this setting is useful for cases where the current row is irrelevant, or where you don't want to draw the user's attention to the grid until necessary.

Changing Colors and Fonts for Individual Columns

TrueGrid includes a large number of properties for customizing the fonts and colors used for headings, columns, and for cells.  The following properties are commonly useful for customizing the appearance of columns:

ColumnBackColor, ColumnForeColor
These colors are used for displaying a given column in a given color.  With these two properties you can set the color of each individual column.

ColumnFontStyle
This property specifies the font to be used for the text within cells of the column.  By default, this property is set to 0, which means that the default grid font (set with FontName, FontBold, FontItalic, etc.) will be used for the column.

ColumnHeadFontStyle
Changing this property will change the font used for the heading of the particular column.  By default, this property is set to 0, which means that the HeadFontStyle or the default grid font (set with FontName, FontBold, FontItalic, etc.) will be used for the column.

These properties can be set at runtime, usually in your Form_Load procedure, as in the following example

Sub Form_Load ()

Table1.ColumnFontStyle(1) = 2   ' bold

Table1.ColumnBackColor(1) = BLUE

End Sub

In addition, column and heading fonts can be set at design time in the Column Properties Editor.


Using TrueGrid's Multiple Selection Feature

  Multiple selection overview

  How the user selects multiple rows

  Working with the list of marked rows in your programs

  Clearing marked rows using Visual Basic code

  Using multiple selection in callback (Application) mode

Multiple Selection Overview

TrueGrid supports a powerful and convenient means for selecting multiple rows of data and working with them in your programs.  Here are some important features of multiple selections:

1.	Users can select and deselect rows directly using the mouse.

2.	The BookmarkList property contains a complete list of all currently selected rows.

3.	You can modify the BookmarkList directly, and the grid responds by showing or clearing the highlight on selected rows.

4.	The SelectMode property gives you control over how the selection appears and operates.

The SelectMode property has 4 possible values:

0 -	Disabled.  This is the default.  The user cannot select rows using the mouse.  However, if there is an existing selection present (such as one created by adding to BookmarkList), then it will be displayed.

1 -	Enabled.  The user can select rows using the mouse, and any selected rows are displayed.

2 -	Disabled & Hidden.  Like Disabled, the user cannot select rows.  In addition, any existing selection will not be visible.  However, the selection is maintained internally.

3 -	Enabled & Hidden.  An odd setting, where the user may select rows, but they won't be shown.  If you find a use for this, let us know.

You can change the SelectMode at runtime in order to alternately show and hide the current selection.

How the User Selects Multiple Rows

For the user, the selection process is easy.  To select a row, the user moves the mouse into the leftmost margin of the grid until a small checkmark appears.  At that point, they can select a row, or deselect an already selected row.

Here, a grid appears with the mouse in the selection area and two rows (the first and third) selected:

Notice how the color scheme chosen using SelectedForeColor and SelectedBackColor does not conflict with the existing color scheme or marquee presentation.  Making such choices carefully is important to assure that your user interface is easy to understand.

Unless you disable user selection (using SelectMode) the user can always select or deselect records, whether they were selected by the program (using BookmarkList) or whether they were originally selected by the user.  This can be very useful.  For example, an initial selection set can be highlighted using a query, then the user can add and remove records at their discretion.

Working with the List of marked Rows in your Programs

The grid maintains a list of all selected rows in the BookmarkList property.  This property contains a list of bookmarks, each corresponding to one of the selected grid rows.  The BookmarkCount property indicates how many bookmarks are currently in the list (and hence how many rows are selected).

You can use the BookmarkList to monitor the selection being made by the user, or to add additional selected rows of your own.  For example, once a selection is made, you could use the following code to go through the marked rows one at a time and perform some operation on each:

For i% = 0 To Table1.BookmarkCount - 1

' Position to the row

Data1.RecordSet.Bookmark = Table1.BookmarkList(i%)

' Process the current row, then move on

ProcessCurrentRecord Data1

Next i%

Note that changing the Bookmark property for the current Data Control's RecordSet will have the side effect of positioning the grid to the new location.  You may want to create a clone of the record set so you can process each record without affecting the rest of your application.

You can add bookmarks to the list of bookmarks for a grid, which will cause them to be highlighted.  To do this, you assign to the BookmarkList using an index one higher than the highest bookmark:

Sub HighlightManagers()

' Set criteria for FindFirst/FindNext

criteria$ = "TITLE = " + chr$(34) + "Manager" + chr$(34)

' Loop through, adding each manager to the BookmarkList

Data1.RecordSet.FindFirst criteria$

While Not Data1.RecordSet.NoMatch

Table1.BookmarkList(Table1.BookmarkCount) = Data1.RecordSet.Bookmark

Data1.RecordSet.FindNext criteria$

Wend

End Sub

Clearing Marked Rows using Visual Basic Code

You can use the BookmarkList to clear selected rows as well:

1.	To clear a single row, set the corresponding element in the BookmarkList property array to an empty string ("").  When you do this, the grid decrements the BookmarkCount property automatically and moves all subsequent bookmarks down by one index position, thus removing the deleted bookmark.  At the same time, any highlighted rows corresponding to the bookmark will no longer be highlighted.

2.	You can clear the entire selection by setting BookmarkCount to zero (0).

Using multiple selection in callback (Application) mode

TrueGrid Pro allows you to select multiple rows even if you are not bound to the database.  Using the QueryMark and MarkChange events you can maintain your own 'bookmark list' and enable multiple selection using the default check mark method or any other method through programmer control.

If you wanted to maintain selected rows using the check mark then simply maintain an array the same size as the number of rows in your data array.  In the MarkChange event toggle the boolean value for that row:

Sub Table1_MarkChange (Row As Long, IsMarked As Integer)

Marked(Row) = Marked(Row) Xor True	' Toggle between True/False

Table1.RefreshRow = Row	' Refresh Row so that the

' row will be properly

' highlighted (or un-highlighted)

End Sub

Note that wherever you implement marking, be it the dbl_click, markchange, or another event, you need to call a RefreshRow on the current row to have it display the row as selected.

When the data is refetch the QueryMark event is called.  QueryMark controls whether or not the current row should be displayed as selected or regular.

Sub Table1_QueryMark (Row As Long, IsMarked As Integer)

IsMarked = Marked(Row)

End Sub

By setting the IsMarked parameter to True you are marking the current row.  The grid takes care of automatically highlighting that row with the SelectedForeColor and SelectedBackColor.  QueryMark is only valid when the grid is in callback mode.  In database mode this event is ignored.


Locked Columns and Introduction to Splits

  Introduction to TrueGrid splits

  Creating locked columns in the Layout Editor

  Creating splits at design and run time

  Choosing to use global or split-specific settings

  User interaction when splits are present

Introduction to TrueGrid Splits

TrueGrid has a set of features for creating and manipulating splits.  A split is similar to the "split window" capabilities available with products like Excel and Word for Windows.  Splits affect a large number of properties, and there are properties designed specifically for working with splits.  Splits open up a whole world of possibilities, and we recommend that you master TrueGrid's other features before learning too much about splits.  TrueGrid defaults for the split properties are set so that you can ignore them until you want to use them.

This section provides a basic overview of splits, assuming that you're just getting started with the split features.  If you want to become an expert, advanced overviews are provided under Realizing the Full Potential of Splits.

For beginning users, splits can provide the following capabilities:

1.	You can easily lock columns at the left margin of the grid.  The design-time Column Properties Dialog contains a special "Locked at left" checkbox which allows you to easily lock one or more columns.

2.	By changing the SplitLocked property to False, you can give your users the interactive capability to create their own splits, just like Excel does.  For the most part, changing this property alone will increase the usefulness of your applications at runtime.

The following sections describe some of the simpler uses for splits, and some of the ways you can use splits quickly and easily.

Creating Locked Columns in the Layout Editor

The Layout Editor has a special feature for making splits easy if you simply want to lock columns at the left of the grid.  Here are the steps you need to follow:

1.	Put a Visual Basic Data Control on your form and define the the required database properties.

2.	Now, set the DataSource property of the grid to the Data Control you just added to your form.

3.	Click with the right mouse button on the TrueGrid control to bring up a default layout.  TrueGrid will use the field definitions from the Data Control automatically.  Now click again with the right mouse button to bring up the Layout Editor.

4.	Once you are inside the Layout Editor, click with the right mouse button on the column you want to have locked.  This will bring up the Column Properties Dialog.

5.	In the Column Properties Dialog you will see a check box labeled "Locked at left".  Check the "locked at left" checkbox to lock the current column.

That's all there is to it.  TrueGrid automatically creates a split for you and sets its properties so that the column you've chosen is locked in the leftmost split.  If you want to lock more than one column simply move to the next column and click on it's locked check box.  Once you have locked all the columns you want you can go back to the Layout Editor and arrange their order.

TrueGrid will allow you to use the "Locked at left" checkbox only if you haven't created any splits yourself, and if SplitPropsGlobal is set to True (the default).  Otherwise, TrueGrid assumes you know how to set up splits yourself and the "Locked at left" checkbox will be grayed-out.  Even for advanced users, it may be convenient to set up locked columns, then begin customizing the splits.

See the Layout Editor for a complete description of how to use the Layout Editor at design time.

Creating Splits at Design and Run-time

Whenever you are working with TrueGrid, you are always using a split.  TrueGrid initially contains only one split.  Its SplitIndex is 1.  It is initially a locked split, meaning that you cannot resize it, or interactively create a new split to divide it.  If you are using TrueGrid's "locked at left" feature, you may not need to know too much about splits, since TrueGrid automatically handles the creation of a split for you.  Once you begin configuring splits yourself, the "locked at left" feature will be grayed-out, assuming that you know how to set up splits yourself.

At design time, you can enable interactive splitting by setting the value of SplitLocked to False.  When you do this, you will notice a small split size box which appears at the leftmost boundary of the horizontal scrollbar.  Once unlocked, you can use the size box to create a new split in the Layout Editor.  When you run your application, the initial configuration of splits will be exactly the same as you set them at design-time.

After you set up the splits you want at design-time, you may choose to reset SplitLocked to True so that your users cannot change the configuration of splits.

Splits are easy to create at runtime, using one of the following techniques:

1.	If you leave SplitLocked set to False, then it will be possible for your users to create their own splits by dragging the split size box to a new position.  For many users, this provides a great deal of flexibility since they can customize the grid to look the way they want.  Sometimes (but not usually) your code may need to be aware of the presence of splits.  This is especially true if your code frequently changes the value of any of the split-specific properties.  By default, however, changes to any property affect all splits, so most code will work unmodified if you allow your users access to unlocked splits.

2.	You can create splits directly in code by changing the value of the Splits property, which reflects the current number of splits.  This technique allows you to create runtime splits for your users without giving them interactive control of splits.

3.	TrueGrid is provided with the utility functions TgLockColumnLeft, TgLockColumnRight, and TgUnlockColumn to simplify the use of splits for locked columns in your code.

Creating a split at runtime is simple:

' Create a new split

Table1.Splits = Table1.Splits + 1

The above line makes a new split.  The split is always created at the right of the grid by splitting the current right split in half.  The column layout of the new split will be the same as for the split which was previously at the right.

If you give your users control over splits, it may be important to allow them to return to a "default layout" for the grid.  TrueGrid allows you, in one line of code, to save or restore the complete grid layout using the value of the Layout property, and this may be convenient for controlling the grid's appearance at runtime.  For example, the following code saves the current layout in a global variable called savedLayout, then enables splitting for users:

' save the current layout so the user can get it back,

' then let them use splits

savedLayout$ = Table1.Layout

Table1.SplitLocked = False

Later, when you want to return to the original layout, you can simply say:

Table1.Layout = savedLayout$

Since SplitLocked settings are part of the layout, you don't need to reset SplitLocked to True to disable splits, providing it was True when you originally saved the layout.

Choosing to Use Global or Split-Specific Settings

For many applications with splits, it is not necessary to control the behavior of each split individually.  For example, if you simply allow users to create their own splits (by setting SplitLocked to False), it often will not matter what each split contains since splits are solely for the convenience of the user.

Thus, by default, when you change any properties, TrueGrid applies the change uniformly across all splits in the grid.

Sometimes, however, it is useful to be able to customize the appearance of one split while leaving the other splits alone.  This capability is controlled by the SplitPropsGlobal setting.  The default setting of SplitPropsGlobal is True, which means that any property setting is applied to all splits.  Setting SplitPropsGlobal to False tells TrueGrid that changes to any of the split-specific properties are applied only to the current split.

The SplitIndex property always contains the number of the current split, and it can be inspected or changed in your code.  You can also monitor which split is current by placing code in the SplitChange event, which is triggered each time your users move to a new split, or whenever you change SplitIndex yourself in code.

Since SplitPropsGlobal affects a large number of properties, you need to be careful how you use it.  Keep in mind that your program may behave differently depending upon the setting of this property.  Make sure you leave SplitPropsGlobal in the state your application will most often expect it.

For example, assume you want to create a locked split at the left with one column in it.(column 2, for example):

' Make properties split-specific and create a new split

Table1.SplitPropsGlobal = False

Table1.Splits = Table1.Splits + 1

' Now, hide all but column 2 in the left split, and hide *only*

' column 2 in the right

Table1.SplitIndex = 1

For i% = 1 To Table1.Columns

If i% <> 2 Then Table1.ColumnVisible(i%) = False

Next i%

Table1.SplitIndex = 2

Table1.ColumnVisible(2) = False

' Resize the left split so that it always contains just 1 column

Table1.SplitIndex = 1

Table1.SplitSizeMode = 2   ' size to a number of columns

Table1.SplitSize = 1       ' one column wide

' Reset SplitPropsGlobal

Table1.SplitPropsGlobal = True

Notice that the above code is careful to reset SplitPropsGlobal when it is through changing split-specific properties.  Such techniques are a good idea if your code uses both modes.

User Interaction when Splits are Present

When the TrueGrid control contains splits, either created by code or created by the user, there are some differences in the way users interact with the grid:

1.	Only one split is current, indicated in your code by the value of SplitIndex.  The current split will use the HeadForeColor and HeadBackColor for its headings.  All other splits use the InactiveForeColor and InactiveBackColor.

2.	When a user selects a cell, they also select a split.  When this occurs, your code receives the SplitChange event.

3.	By default, there is only one marquee (in the current split), even though each split maintains its own ColumnIndex value.  You can change this behavior with the MarqueeUnique property, which causes each split to have its own marquee.

4.	By default, the tab and arrow keys remain inside the current split.  However, using SplitTabMode, you can have the tab and arrow keys move from the last column of one split to the first column of the next (and vice versa).

For the most part, your code doesn't need to be concerned which split is current, since referring to column properties using ColumnIndex will yield the proper values regardless of which split is present.  Only if per-split customizations are used may it be important for your code to be aware of the current split.


Using Unbound and Calculated Columns

  What are unbound and calculated columns?

  How to use unbound columns

  How to use calculated columns

What are Unbound and Calculated Columns

Normally, TrueGrid automatically displays data from database fields.  However, often you may want to augment the set of fields present in your layouts with columns derived from database fields, or columns which are unrelated (or only loosely related) to database information.  For example, if your database contains a "Balance" field, you may instead want to display two columns, "Credit" and "Debit" to show positive and negative numbers separately.  Or, you may want to look-up data in another database, or convert field data to some other form (such as converting coded fields to their textual meanings).

To accomplish such feats, you can use either calculated or unbound columns.  In both cases, you need to specify the column type as calculated or unbound.  You can do this in the Column Properties Dialog or you can set the ColumnType property at runtime.  Each column type works in the following way:

1.	Calculated columns are automatically calculated by TrueGrid based upon a Visual Basic expression you provide.  You set the expression in the Column Properties Dialog, or by setting the ColumnExpression property at runtime.  TrueGrid supports the full Visual Basic expression syntax and over 35 of the most-needed (we think) functions.

2.	Unbound columns require that you provide code in the UnboundFetch event which returns the data which should appear in the column.  This mode is the most flexible, since you can perform any operation you desire to derive a value for the column.

In many cases, the choice of a calculated column or unbound column is arbitrary,  However, each column type has strengths and weaknesses:

1.	Calculated columns are the easiest, since TrueGrid does most of the work for you.  All you need to do is provide an expression.  Calculated columns are also faster than unbound columns, since TrueGrid doesn't have to call your Visual Basic code to display the cell data in the column.  Another advantage which is not obvious is that, for calculated columns, TrueGrid knows which columns depend upon other columns, so it can keep the display updated when data is modified by the user.

2.	Unbound columns, although less efficient than calculated columns, provide maximum flexibility.  In the UnboundFetch event, you can perform any steps necessary to derive values for the column, including performing lookups in other databases.

How to Use Unbound Columns

Using an unbound column requires two steps:

1.	You must set the column type for the unbound column by either checking "Unbound" in the Column Properties Dialog, or by setting the ColumnType property at runtime.

2.	In the UnboundFetch event, you must write code which will provide the value for the column when it is needed.

Here is a simple example of an UnboundFetch event which simply puts the row and column number in the cell:

Sub Table1_UnboundFetch (Row As Long, Col As Integer, Bookmark As String, Value As String)

' Set the Value argument to the cell contents

Value = "Row " & Row & ", Col " & Col

End Sub

Notice that all that is necessary to return the value is setting the "Value" argument to a string which will be placed into the cell.

Usually, the code you write in UnboundFetch will need to refer to information in the database.  In this case, there are several things you need to be aware of:

1.	When UnboundFetch is called, the current row of the database is usually not the same as the row being fetched.  Why?  Because UnboundFetch may need to fetch data which is unrelated to the current row position (which TrueGrid tries not to change if it doesn't need to).  For example, if a row is being edited and the user scrolls the grid horizontally, TrueGrid will need to fetch the data for columns which come into view.  But, changing the current row would cause an update to occur, so TrueGrid doesn't change the current row when fetching data for the new column.  For this reason, you too should avoid making any changes to the current row position or relying on the database position in UnboundFetch.

2.	The "Bookmark" parameter contains the bookmark for the row being fetched.  You can use this bookmark in two ways.  The first way is to move the database position to the bookmarked row in order to access the row.  This is not recommended because setting the bookmark for the Recordset TrueGrid is bound to will change the database position, perhaps causing an unwanted update to occur.  The next way you can use the Bookmark property is to set the bookmark of a clone of the Dynaset to which TrueGrid is bound.  Cloned dynasets share the same bookmarks, so no harm is done by working with a clone.

3.	For the duration of the UnboundFetch event, TrueGrid's ColumnText property will refer to the row being fetched instead of the current row (which is the normal reference point for ColumnText).  Obtaining database values for the current row using ColumnText is highly recommended and very efficient.

For example, assume that you want an unbound column to contain the word "Overdue" if the due date (in another column) is before today's date.  Here's how you would do it:

Sub Table1_UnboundFetch (Row As Long, Col As Integer, Bookmark As String, Value As String)

' Compare the due date in column 3 to today's date

If CvDate(Table1.ColumnText(3)) < Now Then

Value = "Overdue"

Else

Value = ""

End If

End Sub

Notice that the value of ColumnText(3) is used to get the due date for the fetched record.  Since ColumnText always returns the unformatted value (before EditMask is applied), you can easily convert the text to the data type desired with one of Visual Basic's conversion functions, as shown above.

If you have several unbound columns, you will need to check the column number passed as an argument to make sure you are returning data for the proper column.  For example, assume that columns 2 and 5 are unbound.  Here's the way UnboundFetch might look:

Sub Table1_UnboundFetch (Row As Long, Col As Integer, Bookmark As String, Value As String)

Select Case Col

Case 2

' Provide the Value for column 2

Case 5

' Provide the Value for column 5

End Select

End Sub

How to Use Calculated Columns

Calculated columns are a more direct way to provide derived data for a column (you can also use unbound columns).  Using calculated columns requires two steps:

1.	You must set the column type for the calculated column by either checking "Calculated" in the Column Properties Dialog, or by setting the ColumnType property at runtime.

2.	You must also provide a Visual Basic Expression at design-time in the Column Properties Dialog, or by setting the value of the ColumnExpression property at runtime.

The expressions used for calculated columns can use any of the Visual Basic operators and a large number of Visual Basic functions supported by TrueGrid.

Since TrueGrid need not call UnboundFetch each time it needs column data, using calculated columns is often faster than using unbound columns.

Often, you can accomplish the same result with a calculated column as you can for an unbound column.  For example, in the previous section an example set an unbound column to "Overdue" if a due date (in another column, 3) was before today's date.  Here's an expression you could include in a calculated column to accomplish the same result:

Iif(CvDate(ColumnText(3)) < Now, "Overdue", "")

Notice that, within a calculated expression, TrueGrid allows you to use a special function called ColumnText to access the text value of other columns in the grid.  You could also use the field name directly in the calculated expression:

Iif([Due Date] < Now, "Overdue", "")

There is an important difference between these two techniques:

1.	Using the field name (as in "[Due Date]" above) accesses the current value of the database field rather than the value as it appears in the grid.  Normally these will be the same, but if a user updates cell data, it is not written to the database until there is a row change, or until an Update occurs explicitly in code.  So, the second example above would reflect the overdue status of the original record rather than reflect any changes the user has made but not yet updated.

2.	Using ColumnText allows you to refer to the current cell contents rather than the original data.  This is often the desired behavior, since the column values will change dynamically as the user updates dependent data in the same row.

Your choice of technique is dependent upon the needs of your application.  For display-only grids, it doesn't matter.  For updatable grids, you need to decide whether you want the database data, or the cell data using ColumnText.


Using TrueGrid in Callback (Application) mode

 Introduction to TrueGrid Callback mode

 Steps to create a Callback mode application

 Creating a user friendly callback program

 Using the CheckRow event

  Displaying graphics in cells

Introduction to TrueGrid Callback mode

When used in "Application (or Callback) mode"  (i.e., the DataMode property of the grid is set to 1) the grid is not connected to a database file.  Instead, data in the grid will be supplied and maintained by the programmer while the grid takes care of all user interaction and data display.

For example, the user may cover the grid (either completely or partially) with another window and later uncovers it.  The grid will be completely responsible to determine when and what portion of the grid need to be repainted, while the programmer does not need to know about any user interaction or display requirement at all.

The programmer needs only to concentrate on maintaining his data.  When the grid needs to display data on the screen, it will ask the programmer for it via the Fetch event.  Conversely, after user has made changes to the data in the grid, the grid will notify the programmer of the changes via the Update event so that the programmer can update his data to reflect the changes.  If data is changed internally rather by user editing on the grid, the programmer should notify the grid to repaint either by using the RefreshRow or RefreshColumn property, or by using the Refresh method.

The programmer should also make use of other TrueGrid events to make his application user friendly.  These techniques are illustrated in the sections below and in the dBTable sample application that is included which with the TrueGrid product.

Steps to Create a Callback Mode Application

The basic steps for creating a TrueGrid application using callback mode are described below:

1.	Determine method to store data.  The programmer is responsible to maintain and store data to be displayed on the grid.  The most common way is to store the data in Visual Basic arrays.  If the grid is very large (say, 1,000,000 rows by 5,000 columns), there may not be sufficient system memory to store the arrays and the programmer then needs to store the data in files or other storage media.  (When that happens, databases are usually used to store the data and the programmer reverts to using the Database mode of the grid.)  Another possibility is data displayed in the grid depends on some formula (usually a function of row and column numbers).  The programmer then defines the data formula in the Fetch event.

2.	Initialize the data and the grid.  As soon as the grid is loaded it will start asking the programmer (via the Fetch event) for data to display.  So the programmer should initialize the data before the grid is ready.  A good place to do this is either the Main procedure (if you start you program with Main) or the Form_Load procedure (for the Form which contains the grid).  The programmer then has to initialize some grid properties.  Some of the grid properties can be initialized at design time using either the properties window or the TrueGrid Layout Editor.  We will illustrate below how to initialize some properties at runtime. Assuming you have a 3 rows by 2 column table entry and you store the data using a two-deminsional array, the following code initializes the data and grid properties:

' Declare grid data as global array in some global module

Global GridArray(1 to 2, 1 to 3) As String

' Initialize array data in Main() or Form_Load()

For i% = 1 To 2

For j% = 1 To 3

GridArray(i%, j%) = "Row + Str$(j%) + , Col" + Str$(i%)

Next j%

Next

' Assuming the control name of the grid is Table1, initialize

' grid properties in Form_Load():

' Define column heading text.  This can be done in code at

' runtime or in the Layout Editor during design time.

Table1.ColumnName(1) = "Col 1"

Table1.ColumnName(2) = "Col 2"

' Maximum number of characters allowed for columns.  (i.e.,

' User can enter no more than the number of characters

' specified below.)

Table1.ColumnSize(1) = 16

Table1.ColumnSize(2) = 16

' Columns display widths (in characters).  ColumnWidth are

' usually bigger than ColumnSize so that the table will look

' nice and will not be crowded.

Table1.ColumnWidth(1) = 20

Table1.ColumnWidth(2) = 20

' Column styles.  Specify left, center, or right justified.

' Also specifies if a column is read-only (i.e., user cannot

' edit that column).  The column style constants are defined

' in TGCONST.TXT (in your TrueGrid installation directory).

Table1.ColumnStyle(1) = GRS_LEFT + GRS_READONLY

Table1.ColumnStyle(2) = GRS_RIGHT + GRS_READONLY

' Define number of rows in the table.

Table1.Rows = 3

' Initialize current cell position to upper left corner:

Table1.RowIndex = 1

Table1.ColumnIndex = 1

Note that the grid originally has zero number of columns, as you start setting the 1st, 2nd, column properties, etc., the number of columns automatically increases. Alternatively, you can set the number of grid columns by saying:

Table1.Columns = 2

3.	Define the Fetch event.  After the grid is loaded, it will start asking the programmer for data to display.  This is done via the Fetch event.  The programmer feeds data to the grid according to the Row and Col values:

Sub Table1_Fetch (Row As Long, Col As Integer, Value As String)

Value = GridArray(Col, Row)

End Sub

The programmer cannot make any assumption as to when the grid will ask for data.  Also, the programmer cannot make the assumption that if data for a certain Row/Col is asked once, the grid will not ask for it again.  In short, it's the programmer's responsibility to store and maintain the data, and it's the grid's responsibility to display them properly.  This technique will free the programmer from worrying when and how to display data in the grid.

4.	Define the Update event.  After the user has finished editing data in a cell and the data has been validated by the programmer via the Validate event, the grid will then notify the programmer the cell now has a new value via the Update event.  In this event, the programmer uses the value supplied by the grid to update the data he or she is responsible for storing and maintaining:

 Sub Table1_Update (Row As Long, Col As Integer, Value As String)

GridArray(Col, Row) = Value

End Sub

5.	Refresh the grid if data has been changed by the program.  If data is changed by the program instead of by the user editing on the grid, the programmer must notify the grid of the changes so that the grid will properly display the updated data.  This can be done by one of the following three methods:

' Using the RefreshRow property to repaint a row (in this

' example, row number 2):

Table1.RefreshRow = 2

' Using the RefreshColumn property to repaint a column (in

' this example, column number 1):

Table1.RefreshColumn = 1

' Using the Refresh method to repaint the entire grid:

Table1.Refresh

Creating a User Friendly Callback Program

This section describes using three TrueGrid events to assist user in the data entry process and thus creating a user friendly table entry program.  The events used in this application are only some of the TrueGrid events available.  After learning this application, you should familiarize yourself with all available TrueGrid events and start using them to create your own user-friendly applications.  Also, examine the dBTable sample application for more details.

1.	Using the KeyPress event.  The programmer can use KeyPress event to restrict and modify user key input.  The following example converts the user key entry to upper case letters, and restrict the user entry to letters and digits only.

Sub Table1_KeyPress (KeyAscii As Integer)

' Convert key to upper case

ToUpper KeyAscii

' Cancel user key input if it is not a letter or a digit

If (KeyAscii < 65 And KeyAscii > 90) And (KeyAscii < 48 And KeyAscii > 57) Then

KeyAscii = 0

End If

End Sub

2.	Using the Validate event.  Before moving to another grid cell, this routine lets the programmer examine the value in the current cell.  If the value entered is invalid, the programmer can (optional) display a message, then set Cancel to True to prohibit the user moving on to another cell.  The Validate and KeyPress events together provide a very easy way for programmers to check, restrict and validate user input in TrueGrid.

Sub Table1_Validate (Row As Long, Col As Integer, Value As String, Cancel As Integer)

Select Case Row

Case 1

' Valid if starts with "Row 1"

If Left(Value, 5) = "Row 1" Then Exit Sub

Case 2

' Valid if start with "Row 2"

If Left(Value, 5) = "Row 2" Then Exit Sub

End Select

' Display warning message for user

MsgBox "Invalid Value"

' Data validation fails, prohibit user from moving to

' another cell

Cancel = True

End Sub

3.	Using the ColumnChange event.  You can use the _ColumnChange() event to display a different help string when the user is at different table column.  This is to make the program user friendly by assisting the user during the data entry process.

Sub Table1_ColumnChange ()

' When this event is called, ColumnIndex has the new column

' position value

Select Case

Case 1

' Display help string at Label1

Label1.Caption = "Please enter value for Column 1"

Case 2

' Display help string at Label1

Label1.Caption = "Please enter value for Column 2"

Case 3

' Display help string at Label1

Label1.Caption = "Please enter value for Column 3"

End Select

End Sub

Using the CheckRow event

This section is intended for those creating advanced callback-mode applications and assumes a good working knowledge of how TrueGrid works in callback mode.  The remainder of this discussion assumes that TrueGrid is being used in callback mode.

Most callback mode programs require a fixed number of rows.  That is, the value of the Rows property can be easily determined.

However, some applications display data where the number of rows is dynamic, or even indeterminate.  For example, when displaying results from an SQL query, you may not know how many rows are present until you reach the end of the dataset.

When the number or rows is not known, programming can be more difficult, since it is not easy to determine where to change the number of displayed rows.  TrueGrid 2.1 now includes a special event, CheckRows, designed to assist you in creating such applications easily.

In TrueGrid 1.0 and 2.0, such applications usually determined that there were no more rows in the Fetch event (where data is being returned to the grid).  Unfortunately, because of TrueGrid's design, it is not possible to change the number of rows in the Fetch event.  CheckRows was designed to handle such situations.

TrueGrid fires the CheckRows event before it scrolls to a new position in the database.  The CheckRows calling sequence is as follows:

Sub Table1_CheckRows(RequestRows As Long, CurRows As Long)

RequestRows will contain the highest row number TrueGrid wants to display.  For example, when you scroll down or page down, TrueGrid determines what the new bottom row displayed would be, and RequestRows is then set to that value.

CurRows contains the number of rows currently defined for the grid (previously using Rows).  This value may be changed within the event to indicate a new row count.  Within CheckRows you may increase the number or rows, or decrease them.  TrueGrid will automatically adjust all internal structures to reflect the change.

There are several strategies you can use in conjunction with CheckRows.  Imagine a scenario where data is being displayed from a record source, but you don't know how much data will need to be displayed.  Here is how you can use CheckRows to easily cope with such a situation:

1.	Initially, set the value of Rows to a number which you know is larger than the number of rows to be fetched.  For example, if you are making an SQL query, you could set this value to the total number or rows in the database, or you could set it to a large number such as 1 million (if your database is smaller than that).

2.	In CheckRows, pre-fetch data up to the value specified by RequestRows and store it locally.  If you run out of data, then set the CurRows parameter to the new row count.

3.	In Fetch, your code can now assume that any fetched row is legal, since CheckRows has screened the input before Fetch executes.

CheckRows will always be called before Fetch is called.  Thus, so long as CheckRows assures that the requested row exists, or modifies CurRows accordingly, Fetch will never be called with a non-existent row number.

An alternate strategy is to keep the CurRows value ahead of the RequestRows value by some fixed amount (say 100 rows).  Thus, you would pre-fetch rows ahead of those requested so that the scrollbar always appears to be near the end of the dataset, but not quite there.

Ultimately, how you use CheckRows depends upon the specifics of your application.  It is intended for users implementing advanced interfaces where more control is required.

Displaying graphics in cells

TrueGrid provides two methods of displaying graphics in cells:

1.	Value Lists.  Value lists, described in the addendum section Introduction to value list allow you to associate a picture with a specific database value.  This method is very easy, and requires no programming.

2.	UnboundFetch and Fetch.  In an unbound column, or in columns used in a callback (non-database) grid, you can display pictures in selected cells by returning a picture instead of text.

This section describes the second technique, which is less frequently used, but more powerful than value lists.

The UnboundFetch and Fetch methods are normally used to return data to TrueGrid for display.  UnboundFetch is used for unbound columns which are used with a database.  Unbound columns are columns not directly linked to the database.  Fetch is used in non-database grids where all data is provided by the user.

Both Fetch and UnboundFetch have a parameter called Value which you assign a value to be displayed in the cell.  For example, the following Fetch event will fill each column with its cell coordinate:

Sub Table1_Fetch(Row As Long, Col As Integer, Value As String)

' Return the cell coordinate

Value = "Row=" & Row & " Col=" & Col

End Sub

Typically, code you write in these events fetches text to be displayed by TrueGrid.

In TrueGrid Version 2.1, you can use two alternate means for returning the value to TrueGrid in these events.

First, you can assign to the Text property instead of assigning to the Value argument.  Therefore, the following code works identically to the example above:

Sub Table1_Fetch(Row As Long, Col As Integer, Value As String)

' Return the cell coordinate

Table1.Text = "Row=" & "Col=" & Col

End Sub

This use of the Text property is special, and in no way relates to other uses of the Text property, which normally accesses the text value of the current cell.  If you use Text in this way, any change you make to the Value argument will be ignored.

Similarly, you can return a picture to be displayed in the cell by assigning to the Picture property.  For example, the following code displays one bitmap (PicEven) for even numbered rows and another bitmap (PicOdd) for odd numbered rows:

Sub Table1_Fetch(Row As Long, Col As Integer, Value As String)

' Display PicEven for even rows, PicOdd for odd rows.  PicEven and

' PicOdd are hidden controls elsewhere on the form

If Row And 1 Then	' odd numbered row

Table1.Picture = PicOdd.Picture

Else

Table1.Picture = PicEven.Picture

End If

End Sub

How you use these capabilities is up to you.  You can even display text in some cells, and pictures in other cells, depending upon your needs.

TrueGrid supports bitmaps only (no metafiles or icons).  If you have a metafile or icon, you can store it by using its Image property instead of its Picture property:

Table1.Picture = AnIcon.Image


 Column Summary Features

  Introduction to Column Summary Features

  Using Column Summaries

  Providing a seed value

Introduction to Column Summary Features

Sometimes, it is useful to keep running totals for database columns.  For example, in order entry applications, running totals for orders are usually required.  TrueGrid contains a set of properties for automating summary information for columns.

Using these features, you can:

1.	Specify that TrueGrid keep column summaries for individual columns.

2.	Use the ColumnSumChange event to control where and how the summary information is displayed.

3.	Seed the summary value (if desired) so TrueGrid doesn't have to calculate summaries by looping through the database.

The column summary features are available only under program control using two special properties (ColumnSumEnable and ColumnSum) and an event (ColumnSumChange), but TrueGrid takes most of the work out of column summing by pre-calculating the sum and maintaining the sum information internally as data is changed.

Using Column Summaries

Column summaries properties are easy to use, but it is up to the programmer to display the summary information (TrueGrid will not automatically display column totals).  The best way to do this is by placing a text box beneath the column you want a summary of, then using the ColumnSumChange event to update the text box whenever TrueGrid tells you that the summary information has been changed.

Here are the steps needed to maintain and display column summaries:

1.	In your Form_Load event, enable column summaries for the selected columns by setting ColumnSumEnable to True for the columns you want to summarize.

2.	Place text boxes on your form to hold the running total for the selected column or columns.

3.	In the TrueGrid ColumnSumChange event, copy the value of the ColumnSum property to the text boxes you added in step 2.

Once set up, TrueGrid will automatically assure that you are informed (via ColumnSumChange) whenever the sum has changed.  You can then use the value of ColumnSum to update the displayed data (or use it in some other kind of calculation, such as an average calculation).

A simple order entry example will illustrate the techniques used to perform column summary calculations.  The sample presented here is OESUMS (included in your installation directory):

The above order entry grid includes a cumulative total for all items, and a piece count.  Both were calculated using the column summary features.  In the Form_Load subroutine, summaries were enabled for both columns with the following two statements:

Table1.ColumnSumEnable(1) = True

Table1.ColumnSumEnable(5) = True

Once enabled, TrueGrid maintains the sum for each column automatically.  You can access the sum at any time using the ColumnSum property.  When the sum changes, TrueGrid triggers ColumnSumChange.  The sample application has the following code in this event:

If Col = 5 Then

RecalcTotal

ElseIf Col = 1 Then

PieceCount = Table1.ColumnSum(1) & " pieces in order"

End If

Notice that, for column 1, the piece count is simple to obtain since it requires no further calculations.  Since the total requires the addition of tax, a subroutine, RecalcTotal, is used to set the values of all related text boxes:

Sub RecalcTotal ()

Dim tot As Double

Dim taxtot As Double

' Get the total from the grid

tot = Table1.ColumnSum(5)

' Fill in related items

SubTotal = Format$(tot, "Currency")

taxtot = tot * Val(TaxPercent) / 100

TaxAmount = Format$(taxtot, "Currency")

Total = Format$(taxtot + tot, "Currency")

End Sub

Most of the work involves formatting and storing displayed values.  Obtaining the sum is simple.

Providing a Seed Value

Normally, TrueGrid automatically calculates the sum by scanning the database.  Once the initial scan is performed, TrueGrid keeps the internal total up to date by tracking changes to the database, thus avoiding unnecessary file access.

TrueGrid performs its initial database scan the first time you access the ColumnSum property, and recalculates it each time you need the sum after a refresh operation occurs.  However, sometimes, you know the sum in advance.  Perhaps the sum is stored in an order header field.  More advanced users may find it useful to use Visual Basic's SQL features to pre-calculate the sum using the SQL SUM() operator.

If you have a technique for finding the sum, you can provide the initial value to TrueGrid as a seed value.  To provide a seed value, you assign your initial value to the ColumnSum property before accessing it for the first time.  This causes TrueGrid to maintain the seed value, rather than going to the database to calculate a new value.

The best way to manage a seed value is by setting a global flag, indicating that you haven't yet provided the seed.  Then, the first time ColumnSumChange is fired, set the seed value, as follows:

Sub ColumnSumChange (col As Integer)

If TimeToSeed Then

Table1.ColumnSum(col) = CalcSeedValue(col)

TimeToSeed = False

End If

Total.Text = Table1.ColumnSum(col)

End Sub

In the above code sequence, CalcSeedValue is a routine which you need to provide to pre-calculate a seed, or access the seed value from some reliable source (such as an order header, where you know the value is correct).

Once a seed has been set, TrueGrid trusts that it is correct and does not attempt to verify it against the database data.  However, if a database Refresh occurs, TrueGrid will recalculate the sum itself unless you provide the seed again.  In this case, you probably want to set TimeToSeed to True in the Validate handler of your Data Control (but only when refresh is detected).

Although not too difficult, managing seed values can add code to your program.  Unless you absolutely need the performance increase of tracking seed values yourself, we suggest you let TrueGrid do the work for you.


Value List Features

  Introduction to Value lists

  Creating a value list using the Field Values Dialog

  Value list validation

  Specifying a Value List default

Introduction to Value lists

Values from bound or calculated columns can be translated to any textual strings or pictures for display purposes.  Furthermore, programmers can display cell data (original or translated) using built-in radio buttons or combo boxes.

For example, country names may be displayed as pictures of their respective flags, (0,1, 2) may be displayed as (Yes, No, Unknown), either (0, 1, 2) or the translated values (Yes, No, Unknown) may be displayed as radio buttons in a cell or in a drop down combo box.  All these features can be defined (interactively) at design time using the Layout Editor - without writing any code!

The following sections describe how to define value lists interactively, and then how to control their behavior using properties and events in code.

Creating a value list using the Field Values Dialog

To create or update a value list, click the right mouse button over a grid at design time to bring up the Layout Editor.  Position the mouse pointer to the column you wish to define a value list, click with the right mouse button to bring up the Layout Editor column menu:

Choose the Value List... option to bring up the Field Values... dialog.  Alternatively, you may choose the Properties... option to bring up the Column Properties dialog:

Then click on the Value List... button to bring up the Field Values... dialog::

If a value list for the selected column has not been created, the "Data" column in the value list table will be empty.  Programmers should enter valid field values in the "Data" column.  Assuming the selected column (with fieldname "Status") has field values (0, -1).  Enter values 0 and -1 in the "Data" column as shown below:

To delete a value list item, simply position the marquee to the row you want to delete and press the Delete key.  To insert a blank row, position the marquee to the desired row, then press Shift-Ins to insert a blank row above the current row.

If the "Auto Validate" box is checked, the user will not be able to enter any values other than those listed in the "Data" column (in this case, 0 or -1) during program execution.  TrueGrid will beep and the user will not be allow to exit the cell until either 0 or -1 is entered.

If the "Cycle on Click" box is checked, TrueGrid will automatically cycle through all values in the "Data" column whenever the user clicks on the current cell.

Suppose the current cell of the value list table is on the 1st row (with value 0) of the "Data" column, clicking on the "Default Value" box will display the 1st row in italic.  When the program executes, all field values that are not on the value list (i.e., neither 0 nor -1) will be displayed as 0 - the designated default value.  If the "Auto Validate" box is not checked and the user enters a value 2 at runtime, the value 2 will be stored in the database but it will be displayed as 0.

Creating a value list with translated values

Bring up the value list as created in the previous section.  Click on the "Translate Values" box.  A "User Value" column will appear to the right of the "Data" column:

At the "User Value" column you can enter the values to be displayed in the grid.  In the above example, we have entered the values True and False.  During program execution, TrueGrid will display True or False when the field data values are -1 or 0, respectively.  You could just have easily specified Yes/No, T/F, or Y/N in the "User Value" column.

Note that the programmer need not worry about the "User Value" in the code.  Data in the "User Value" column are used by the grid for display purposes only.  The programmer always uses the original field values for all data operations such as data validation, update or query.  Thus the programmer can modify the "User Value" at any time without having to change the code.

If the "Auto Validate" box is checked, the user will not be able to enter any values other than those listed in the "User Value" column (in this case, True or False) during program execution.  TrueGrid will beep and the user will not be allow to exit the cell until either True or False is entered.

If the "Cycle on Click" box is checked, TrueGrid will automatically cycle through all values in the "User Value" column whenever the user clicks on the current cell.

Suppose the current cell of the value list table is on the 1st row of the "User Value" column, clicking on the "Default Value" box will display the 1st row in italic.  When the program executes, all field values that are not on the value list (i.e., neither 0 nor -1) will be displayed as False - the designated default value.  If the "Auto Validate" box is not checked and the user enters a value 2 at runtime, the value 2 will be stored in the database but it will be displayed as False.

Displaying pictures using the value list

Data in the "User Value" column are not limited to textual strings.  The Picture... button allows you to specify a picture to be displayed in place of the "Data" column value.  Click on the "User Value" column for the row in which you wish a picture to be displayed.  Then click on the Picture... button, a File Dialog will appear for you to choose a picture (.BMP) file to be displayed.  In the example below, we have entered the country names in the "Data" column and pictures of their respective flags in the "User Value" column:

The In-Cell Graphic sample that shipped with the TrueGrid product uses a similar picture value list, the ColumnButton property, the ClickButton event and the Visual Basic list box to create a grid with impressive graphics display and a drop down list for easy data entry.

Using check boxes in value lists

One can easily display check boxes in a cell using the value list.  Bring up the value list as described in the Creating a value list with translated values section above.  Instead of entering True and False in the "User Value" column, you can use pictures of check boxes (2 check box pictures, checkon.bmp and checkoff.bmp, are shipped with the product in your TrueGrid installation directory) as shown below:

You should also check the "Cycle on Click" box.  When the user clicks on a current cell with the check box, the check box will toggle between on and off.  The In-Cell Check Box sample that shipped with the TrueGrid product uses the check box pictures and the RequestEdit event to create a grid with a check box column to facilitate data entry.

Displaying the value list with radio buttons

You can also use the built-in radio buttons to display cell data and to facilitate data entry.  Assuming a "Status" field has 4 possible values (0, 1, 2, 3).  Create a value list for the "status" column as described in the Creating a value list using the Field Values dialog section above:

Now click on the "as Radio Buttons" button in the Field Values... dialog.  When the program executes, the "Status" column will be displayed as radio buttons (you can also see how the radio buttons will be displayed at design time if you choose the Show Sample Data option from the Layout Editor control box):

When you click on the individual buttons in the current cell, the field values in the cell will be changed accordingly.  If you have also clicked on the "Cycle on Click" button in the Field Values... dialog, then you can click on anywhere in the current cell (i.e., no necessarily on the individual radio buttons) and the field values will cycle through all possible values in the value list.

Return to the Field Values... dialog and click on the "Translate Values" check box.  Fill in the "User Value" column as shown below:

When the program executes, data in the "User Value" column will now appear next to the radio buttons in a cell:

Displaying the value list with combo boxes

Use the same value list as in the Using the built-in radio buttons section above, except this time click on the "as Combo Box" button and the "Sorted" check box:

When the program executes, a button will appear in the current cell of the "Status" column.  If you click on the button, a list will drop down which contains all the values in the value list.  You can choose a value from the combo list or enter a value in the edit text box similar to the Visual Basic combo box:

If you have not checked the "Translated Values" box in the Field Values... dialog, data from the "Data" column will appear in the combo list box instead.

Note that since the "Sorted" box is checked, the values in the combo list box appears in alphabetical order.  This will work whether data are from the "Data" column or from the translated "User Value" column.

The built-in combo box works only with values defined in the Field Values... dialog.  If you want to use other Visual basic (bound or unbound) controls for editing, see the section entitled Creating a Drop-down List Instead of Editing Cell Text for additional information.

Value list validation

The "Auto Validate" and the "Cycle on Click" check boxes on the Field Values... dialog provide you with automated data entry and validation options when using the value list feature.

When the "Auto Validate" box is checked, and if the "User Value" column contains textual strings, then the user must enter one of the "User Value" strings from the list.  Otherwise TrueGrid will beep and the user will not be allowed to exit the cell.

If "Cycle on Click" is checked, then clicking on the current cell at runtime will cycle through all the items in the value list (whether picture or text).

Always remember that the programmer need not worry about the "User Value" in the code.  Data in the "User Value" column are used by the grid for display purposes only.  The programmer always uses the original field values for all data operations such as data validation, update or query.  Thus the programmer can modify the "User Value" at any time without having to change the code.

Specifying a Value List default

If you want to specify certain values to be displayed as is or translated to a user value yet have all the other possible combinations be displayed as a default option then you can use the Default Value check box.  If Data values are specified then you can click this button on the row that you want to used as the default value.  Then when the grid tries to display a value that is not in the value list it will use the default value.

TrueGrid makes you aware of the fact that you have selected a default value for that column by highlighting that column in italics.


How to Print TrueGrid using Crystal Reports

 Introduction to using the Crystal VBX 2.9 with TrueGrid

 The Bound Report Driver And Bound Report Files

 New Crystal Custom Control Properties

 Crystal Reports Pro 3.0 Upgrade

Introduction to using the Crystal VBX 2.9 with TrueGrid

TrueGrid Pro has built-in support for Crystal Reports Pro 3.0 (CRP 3.0) and the stock version of Crystal Reports (CRVB) that comes bundle with Visual Basic Pro 3.0.  An enhanced CRYSTAL.VBX (v3.0) is shipped with CRP 3.0 which enables users to produce "bound reports" from the Visual Basic Data Control, TrueGrid, or other bound (data-aware) custom controls, it also enable users to produce "bound report .RPT files" for report customization.

TrueGrid Pro ships with a modified version of CRYSTAL.VBX (v2.9) which enables users to produce "bound reports" from TrueGrid, but it does not produce "bound reports" from other bound custom controls, and it does not produce "bound report .RPT files" for customization.  It was specifically designed to enable CRVB users to print reports from the TrueGrid control.  If you already have CRP 3.0, you should use the more full-featured CRYSTAL.VBX that comes with CRP 3.0, and you can skip this section and refer to the CRP 3.0 readme and help files for a complete description of the "bound report" features.

In the following sections, we will describe the new features of CRYSTAL.VBX and its benefits.  Features that are available in CRP 3.0 only will also be described but will be clearly marked.

TrueGrid Pro is optionally bundled with CRP 3.0.  If you would like to upgrade to CRP 3.0, you can call Apex at 800-858-APEX (800-858-2739).

The new CRYSTAL.VBX Custom Control features offer the following benefits:

1.	Generating reports in Visual Basic programs is made even easier and no longer require an existing .RPT file.

2.	A powerful feature of Visual Basic is users can perform ad-hoc queries by executing SQL statements in the RecordSource property of the Data Control.  By directly bounding CRYSTAL.VBX to a Data Control, users can now create reports of dynaset data which are the results of such ad-hoc queries.

3.	Using TrueGrid as the report source (see ReportSource property below), users can perform database queries, view the resulting data in a table format, and generate reports at the same time.  Furthermore, users can perform simple report customization by configuring TrueGrid (hiding columns, adjusting column widths, or rearranging columns) at design time or during program execution.

4.	(CRP 3.0 only) Programmers can generate "bound report .RPT files" and then use the Crystal Report Designer to customize the report layout and even link the bound data to other database tables (just like you do with any other .RPT files).

The Bound Report Driver And Bound Report Files

When you use Crystal Reports to generate reports from database files of a particular file format (e.g., Paradox file format), you need to have the appropriate report driver (e.g., PDBPDX.DLL) to retrieve data from the databases.  Similarly, when you generate reports by bounding to a Visual Basic Data Control, a Bound Report Driver (PDBBND.DLL) is used to retrieve data from the Data Control.  Make sure both CRYSTAL.VBX and PDBBND.DLL is in your Windows system directory or search paths, along with other database drivers.

New Crystal Custom Control Properties

Five new properties are added to CRYSTAL.VBX in order to support Bound reports.  These new properties are described below. Crystal VBX Properties are used to define a state or characteristic of the Report control.  Properties can be set at design time via the properties window.  The contents of the properties can be referenced, and usually modified at runtime also.

(AutoDesign)

DataSource

ReportFooter

ReportHeading

ReportSource

Crystal Reports Pro 3.0 Upgrade

The TrueGrid Pro and Crystal Reports Pro 3.0 (CRP 3.0) combination will give you unprecedented power and flexibility for your database applications. TrueGrid Pro is optionally bundled with CRP 3.0.  If you would like to upgrade to CRP 3.0, you can call Apex at 800-858-APEX (800-858-2739).


Report (AutoDesign) Property

Values	1 - from TrueGrid control

2 - from other bound controls

3 - from data control field list

4 - no default detail line

Description	This property is available in CRP 3.0 only.  It allows you to create Bound .RPT files at Visual Basic design time and is not available at runtime.  Click on the ellipse in the properties window and a "Export Bound Report..." dialog will pop up to allow you to create and save Bound .RPT files.  You can create a .RPT file using one of the following options:

1.	from TrueGrid control  This option creates a Bound .RPT file based on the current configuration of a TrueGrid control on the form.  The TrueGrid control is bound to the same Data Control as the Crystal Custom Control and its layout must first be initialized before this option can be used.  If there are more than one TrueGrid bound to the same Data Control (a very rare occurrence), then the TrueGrid which was created first will be used.

2.	from other bound controls  This option creates a Bound .RPT file based on the DataField properties of all controls which are bound to the same Data Control as the Crystal Custom Control on the form.  TrueGrid bound controls are ignored when this option is chosen.

3.	from data control field list  This option creates a Bound .RPT file based on all the fields in the field list of the Data Control.

4.	no default detail line  This option creates a Bound .RPT file with no fields (or detail line) specified.

After a Bound .RPT file is created, programmers can then use Crystal Reports to customize the report layout or even link the bound data to other database tables.


Report DataSource Property

Usage	report.DataSource = DataControl

Description	This property can be read/write at design time only and is not available at runtime.  This property is ignored if the ReportSource property is 0 (Report files).  To generate Bound reports, set this property to the Data Control you want to retrieve data from.  The Data Control must already be on the form before this property can be set.


Report ReportFooter
Report ReportFooter Property

Usage	report.ReportFooter = boolean

Description	This property can be read/write both at design time and runtime.  This property is ignored if the ReportSource property is 0 (Report files).  Default is False and the Bound reports generated will not have page numbers printed.  It set to True page numbers will be printed at the bottom of a page.


Report ReportHeading Property

Usage	report.ReportHeading = stringexpression

Description	This property can be read/write both at design time and runtime.  This property is ignored if the ReportSource property is 0 (Report files).  It specifies the report title at the beginning of a Bound report.  If blank, no report title will be printed.


Report ReportSource Property

Values	0 - Report file

1 - Bound TrueGrid Control

2 - Other Bound Controls (CRP 3.0 only)

3 - All Data Control Fields (CRP 3.0 only)

Usage	report.ReportSource = numeric expression

Description	This property can be read/write both at design time and runtime

The default value is 0 - Report files, and the ReportFileName property must be assigned to an existing report file pathname (.RPT).  This is equivalent to when the new Bound report features were not available and all reports were generated from existing .RPT files.

When set to 1 the ReportFileName property will be ignored and no .RPT file is needed.  Reports will be created which match the configuration and data displayed in TrueGrid (with has the same DataSource property).

When set to 2 - Other Bound Controls, a Bound report based on the DataField properties of all controls, which are bound to the same Data Control as the Crystal Custom Control, is produced.  TrueGrid bound controls are ignored when this option is chosen.

3 - All Data Control Fields.  This option creates a report based on all the fields in the field list of the Data Control.


 Realizing the Full Potential of Splits

  Overview of TrueGrid splits

  Global properties versus split-specific properties

  Split groups and unsynchronized splits

  Mouse and keyboard interaction with splits

  Configuring the size of splits

 Configuring Splits At Design Time

 Working With Splits in Your Code

Overview of TrueGrid splits

TrueGrid provides a powerful feature not found in any other Visual Basic grid control: splits.  A split is a "view" into your data, and a single TrueGrid control can have as many splits as you wish.

Splits can be created both interactively, using the split size box, or they can be created in your code by using the Splits or InsertSplit properties.  For interactive use, your users will appreciate the ability to split the grid, then scroll the remaining columns interactively.  Splits can also be pre-configured at design time using the Layout Editor.

If you are a new user, you may want to read the section called Introduction to TrueGrid Splits which provides a quick introduction to splits and touches on some of their capabilities.  It is not required reading for this section, as all split topics will be covered in detail here.

Splits were inspired by Excel, Word for Windows, and other Windows products which give the user the flexibility to create views of their data interactively.  We added a wealth of capabilities to TrueGrid's splits to make it easy to create sophisticated tabular interfaces in Visual Basic while still providing the ease of use found in products like those just mentioned.

In detail, splits offer the following capabilities:

1.	Customizability.  Each split has its own set of split-specific properties which you can use to customize the column layout, colors, fonts, and user interaction style for each split.  This customizability allows you to create locked columns, multiple scrollable regions, or fixed "display panels" which can't be edited or selected.  Because a grid can contain as many splits as you wish, and because each is customizable, there is virtually a limitless combination of possibilities.

2.	Synchronization.  You can make splits synchronized, so that each displays the same rows at all times, or you can "unlink" splits so that they can be scrolled independently in a vertical direction.  Synchronized splits can be grouped so that several splits are linked together in this fashion and others are grouped separately.

3.	Keyboard interaction.  Splits can behave like separate grids, restricting keyboard movement to the area of the split, or the keyboard can be configured so that users can tab over split boundaries.

4.	Column configuration.  Most column characteristics can be different in each split, with the exception of a column's field name, calculated expression, heading, or unbound status.  Thus, you can customize column appearance, font, colors, visibility, justification, and many other properties on a per-split basis.

5.	User Control.  You can give your users control over splits by unlocking selected splits.  Within the unlocked area, users can create their own new splits and may remove existing splits.  You combine areas of user control with "locked" areas which the user cannot modify.

Aside from the many split-specific properties, there are many properties which are designed solely for the manipulation of splits:

InsertSplit	Allows you to insert a new split at a given position.

RemoveSplit	Allows you to remove a split.

SplitChange	Event which is fired whenever the user selects a different split, or the split number changes because SplitIndex was changed in code.

SplitEditable	If True, data in the split can be edited.

SplitGroup	Defines the group to which a split belongs, for syncrhonization purposes.

SplitIndex	Returns or sets the current split number.

SplitLocked	If True, then the user can reconfigure the split.  If False, the user cannot remove or resize the split.

SplitPropsGlobal	Changes the property mode so that changes to split-specific properties apply to all splits, or only to the selected split.

SplitSelectable	If True (the default), the user can select the split and its cells with the mouse and keyboard.  If False, then the split is for display only.

SplitSizeMode	Defines the mode used to size a split.  This is either (0) scalable, (1) twips, or (2) number of columns.

SplitSize	This defines the size of the split, using units dependent upon the SplitSizeMode.

Splits	Returns (or sets) the total number of splits in the grid.

SplitTabMode	Controls whether tabs can cross split boundaries.

Global Properties Versus Split-Specific Properties

Once a split has been created, either by locking columns or by allowing users to create interactive splits, the meaning of some of the other TrueGrid properties change slightly.  The most obvious are:

1.	The ColumnIndex property, which reflects the current column number and the location of the marquee, can be different for each split.  So, if you have two splits, each has its own value for ColumnIndex.

2.	Similarly, LeftColumn and RightColumn usually reflect the left and rightmost columns of the grid.  When you have splits, each split has its own values for these properties because each split can have its own horizontal scrollbar, as well as column configuration and layout.

3.	Column-specific properties, such as ColumnWidth and ColumnOrder can be different for each split since each split has its own column configuration.

Properties such as those just described are referred to as split-specific properties because they are different depending upon what split is being referred to.  To determine which split is current, a special property called SplitIndex always contains the number of the current split.  The leftmost split is split number 1, and splits are numbered consecutively to the rightmost split.  When the user clicks on a split, TrueGrid will change SplitIndex so that it reflects the split the user is currently working in.  You can change SplitIndex as well, in order to assure that your property references apply to the split you are interested in.

When you access the value of a property, you are always accessing the value for the current split.  But, when you set the value of the property, TrueGrid allows you to either set the value for the current split, or to set the value for all splits simultaneously.  This mode is set by using the SplitPropsGlobal property.  If SplitPropsGlobal is set to True, then changes made to any split-specific property will be applied to all splits; if SplitPropsGlobal is set to False, then changes made to any split-specific property are made only to the current split.

For example, the following code sequence turns headings on for all splits, then turns them off for the leftmost split only:

' Turn headings on for all splits first

Table1.SplitPropsGlobal = True

Table1.Headings = True

' Turn headings off for the leftmost split

Table1.SplitPropsGlobal = False

Table1.SplitIndex = 1

Table1.Headings = False

By default, SplitPropsGlobal is set to True so that any property changes you make apply globally to all splits.  For simple applications this is usually the desired mode.  Once you start applying properties to individual splits, you need to be sure you are always aware of the value of SplitPropsGlobal so that your code operates as you expect.

You can use SplitPropsGlobal and SplitIndex during design time as well:

1.	When you set SplitPropsGlobal to False at design time, then all split-specific properties refer to the split indicated by the SplitIndex property.

2.	You can change SplitIndex at design time in order to "point" to the split you want to modify.

Until you become proficient with splits, we recommend you keep SplitPropsGlobal set to True, the default setting.

Split Groups and Unsynchronized Splits

All splits are normally synchronized so that they scroll together.  Because of this, the top row of each split always points to the same row number.  However, it is possible to "unlink" splits so that each can scroll independently.

This is done using the SplitGroup property.  All splits which are members of the same group will scroll together and usually share the same vertical scrollbar.  By default, all splits have the same group number: 1.  If you change the group number of one split so that it is different than the others, then it will be able to scroll vertically to a different location than the others.

If you want independent splits, it doesn't matter what group number you choose, so long as it is different from the others.  For example, if you have two splits which have group number 300, and two which have group number 516, each pair will scroll simultaneously and the two groups will be independent of one another.

If you have VertScrollbar set to "2 - Automatic", then TrueGrid will automatically assure that the rightmost split of each group has a vertical scrollbar.  However, you can set the VertScrollbar property to "1- Always" or "0 -None" for selected splits and thus control exactly which split has the scrollbar.  In most cases, the automatic behavior will be just fine.

Although independent splits can scroll to different rows, the current row number (specified by RowIndex will always be the same for all splits).  Therefore, if you select a row in one split, other splits (even those in different groups) will scroll so that the newly selected row is displayed.

When splits are unsynchronized, each split group can have its own values for TopRow and BottomRow.  In all cases, splits can have different values for ColumnIndex, LeftColumn and RightColumn.  Code you write for certain events can be affected by these differences.  Here are the events related to these properties and how they are affected:

ColumnChange	Fired when ColumnIndex changes, or when you change to a split which has a different value for ColumnIndex.

CellChange	Fired when RowIndex or ColumnIndex changes, or when you change to a split which has a different value for ColumnIndex.

LeftColChange	Changed when LeftColumn changes, or when you change to a split which has a different value for LeftColumn.

TopRowChange	Changed when TopRow changes, or when you change to a split which has a different value for TopRow.  If all splits are members of the same group, then this event is only fired when vertical scrolling occurs, since all splits will have the same value for TopRow.

Mouse and Keyboard Interaction with Splits

Depending upon how you are using splits, you may want to change the default behavior of the mouse or keyboard.  Normally, all splits can be selected with the mouse, and the tab and arrow keys will always remain inside the split.

Sometimes, you want a split to appear, but you don't want the user to be able to select it with the mouse.  In such cases, you can set SplitSelectable to False for a particular split and TrueGrid will not allow the user to select (or edit) data in the split.  This is especially useful if you are using a split to simulate row labels and you want the label area to be an uneditable, unselectable panel of data.

Although it is rather unorthodox, setting SplitSelectable to False for all splits will result in a "display only" grid.  The user won't be able to select a cell or perform any editing.

The tab and arrow keys normally allow you to move horizontally from cell to cell, but always stay within the current split.  By setting SplitTabMode to 1, the tab and arrow keys will work across splits.  If you are at the last column of one split, then press the right arrow, you will move into the adjacent split to the right.  The same effect holds true for the leftmost column of a split.

SplitTabMode will only allow tabs between selectable splits (with SplitSelectable set to True).  Unselectable splits are bypassed in the tab/arrow sequence.  This maintains the illusion that unselectable splits are "display panels" rather than actual data entry areas.

Whenever SplitTabMode is 1, TrueGrid will also "wrap" from the last split to the next row in the first split whenever you have WrapCellPointer set to True.

Whenever the user selects a cell within a new split, a number of events may be fired:

CellChange, RowChange, ColumnChange
These events are fired if, in the new split, the cell, column, or row number chosen by the user is different from the one which was current before the selection.  These are fired regardless of whether the user selects with the mouse or keyboard.

SplitChange	When the user selects a new split, SplitChange is fired.  It is fired if the mouse is used to select a split, and also if the tab or arrow keys move to a new split because of the setting of SplitTabMode.

Configuring the Size of Splits

Configuring split sizes can be complex, but TrueGrid handles most of the details under normal use.  This section describes the split size options without sacrificing detail.  If you are just starting out with TrueGrid, you can use splits in a variety of ways without understanding these issues yet.  The Introduction to TrueGrid Splits describes how easily splits can be used using many of the automated TrueGrid features.

TrueGrid supports three different sizing mode for splits, chosen by the setting of SplitSizeMode:

1.	Scalable. (SplitSizeMode=0)
A scalable split uses the value its SplitSize to determine the percentage of space the split will occupy.  For any scalable split, the percentage is determined by dividing its SplitSize value by the sum of the SplitSizes of all other scalable splits.  Thus, you can consider the SplitSize of a scalable split to be the numerator of a fraction, the denominator of which is the sum of the scalable split sizes.  Scalable splits compete for the space remaining after non-scalable splits have been allocated.  By default, all splits are scalable, so they compete for the entire grid region.

2.	Exact Size in Twips.  (SplitSizeMode=1)
An exact split uses the value of SplitSize as an exact number of twips which the split will occupy.  Exact splits will be truncated if they won't fit within the horizontal grid boundaries.

3.	Number of Columns.  (SplitSizeMode=2)
Splits configured in this way use SplitSize to indicate an exact number of columns which should always be displayed within the split.  These splits automatically reconfigure the entire grid appearance if the size of the displayed columns changes, or if the split is scrolled hoizontally so that width of the displayed columns is different.  This mode is especially useful for locked columns, where user resizing of the columns must be reflected automatically in the split size as well.  However, this sizing mode can be used for a variety of other purposes as well.

By default, the SplitSizeMode for splits is "0 - Scalable" and the SplitSize is set to 1.  For example, if you create two splits with the following code

Table1.InsertSplit = 1	' insert one split at the left

Table1.InsertSplit = 1	' insert another

the resulting grid display will look like this:

Notice that each split occupies 1/3 of the total grid space.  This is because there are three scalable splits, and each split has a SplitSize of 1.  If the split sizes were 2, 2, and 3 (respectively), then the resulting grid display will look like this:

Notice that the sum of all split sizes (2+2+3) is 7, so the size of each split is a fraction with the numerator being its SplitSize and a denominator of 7.

When a split is set to exact mode, then that split receives space before the other splits do.  This behavior is somewhat more complex, but if you understand how scalable splits work, it shouldn't be too bad.  For example, assume that splits are set in the following way:

Split #1	SplitSizeMode	0 - Scalable

SplitSize	2

Split #2	SplitSizeMode	1 - Twips

SplitSize	2500

Split #3	SplitSizeMode	0 - Scalable

SplitSize	3

After configuring the splits in this way, the resulting grid display will look like this:

Notice how the fixed size split (#2) is configured to exactly 2500 twips (trust me), and the remaining splits compete for the space remaining in the grid.  Since the remaining splits are both scalable splits, they divide the space among themselves according to the percentages of the remainder calculated using their SplitSize values.  So, the leftmost split occupies 1/3 of the space remaining after Split 2 has been allocated, and the rightmost split occupies 2/3.

Splits set to "Number of columns" mode behave almost identically to exact splits, except that their size is determined by the width of integral number of columns.  The width, however, is dynamic, so resizing the columns or scrolling so that different columns are in view will cause the entire grid to reconfigure itself.

Never create a grid which has no scalable splits.  Although TrueGrid handles this situation, it is difficult to work with a grid configured in this way.  For example, if no splits are scalable, then all splits will have an exact size which may not fill-out the entire horizontal width of the grid.  If the total width of the splits is too short, then TrueGrid displays a "null-zone" where there are no splits.  If the total width is too wide, then TrueGrid will show only the separator lines for splits which can't be shown.  TrueGrid isn't designed to produce a pleasing display when splits fall short of the total width, or when they exceed it.

You'll notice that all of the splits in the above examples have their split size box shown.  That is, they are unlocked (because SplitLocked is False) and users may move the splits interactively.  What happens to the SplitSize and SplitSizeMode when a user reconfigures the splits interactively?  Here's what TrueGrid does:

1.	When the user moves a split size box, two splits are always affected.  If they resize, then the splits bounding the size box are affected.  If they create a split, then the new split and the split to its right are affected.  TrueGrid always changes the SplitSizeMode of both of these splits to "0 - Scalable", but doesn't change the SplitSizeMode of any other splits.

2.	After the user lets go of the size box, TrueGrid adjusts the SplitSize of all scalable splits, so that the two affected splits will have the exact size the user requested.  How TrueGrid does this is not important since the resulting values for SplitSize will keep all splits at the same size and position.  However, the SplitSize values may end up being rather large.  This is because TrueGrid needs to choose the least-common-denominator for the total split size, and the user may position the split bar to any arbitrary position.

If you don't give the user control over splits, by locking splits with SplitLocked, such changes will never occur.  But, you need to be aware of these changes if your code depends upon the SplitSize of scalable splits, and if your users have the ability to resize splits themselves.


Configuring Splits At Design Time
 Realizing the Full Potential of Splits

 Configuring Splits At Design Time

  Creating splits at design time using the Layout Editor

  Setting split-specific properties at design time

  Using the Layout Editor to configure columns in splits

  How locked columns work by using splits

  Giving the user control over splits

 Working With Splits in Your Code

Creating splits at design time using the Layout Editor

With respect to splits, the operation of the Layout Editor is dependent upon the setting of SplitLocked.  If SplitLocked is True for a split, the default, then the split cannot be resized or removed.  This applies both to the runtime environment and the design-time environment in the Layout Editor.

Since the grid contains only one split (SplitIndex 1) when it is first created, and since the default setting for SplitLocked is True, there will be no split size box in the Layout Editor and splits cannot be created.  This default behavior makes it easy to use TrueGrid without using splits at all, and keeps the split capabilities "out of the way" for users who don't need them.

To enable split capabilities at design time, toggle the value of SplitLocked to False.  The Layout Editor will now show the split size box and splits can be created and configured at design time.

If you want to disable split reconfiguration by users at runtime, but still want to be able to manipulate the splits at design time, you need to change SplitLocked to True before releasing your application to users.  Typically, you will set SplitLocked to False while you are configuring TrueGrid at design-time.  Then, you will lock those splits you wish to "freeze" so that users cannot change their size or position when your application is running.

Setting Split-Specific Properties at Design Time

Once splits exist, the setting of SplitPropsGlobal becomes important, both at design time and runtime.  The section entitled Global Properties Versus Split-Specific Properties discusses the difference between global properties (which apply to the entire grid) and split-specific properties which apply only to a selected split.

At design time, the setting of SplitPropsGlobal is respected as well, and has the following effect on your use of TrueGrid:

1.	When SplitPropsGlobal is True, then changing any property value in the Visual Basic Properties window will change the property value for all splits.  When SplitPropsGlobal is False, changes to properties in the property window will affect only the split indicated by the current value of SplitIndex as it appears in the property window.

2.	When you enter the Layout Editor and then bring up the Column Properties Dialog for a particular column, the dialog will be customized depending upon the value of SplitPropsGlobal.  If SplitPropsGlobal is True, then changes you make in the Column Properties Dialog will apply globally to the column in all splits.  If SplitPropsGlobal is False, then some of the settings in the dialog will apply globally while others apply only to the column in the selected split.  The dialog displays those items which are global to all columns in blue while displaying items which apply only to the current split in black.  A legend appears at the bottom of the dialog box to remind you of this behavior.  Click here ( [image] ) to see how the Column Properties Dialog looks in this mode.

Using the Visual Basic properties window, the procedure for making a change to a split-specific property is simple.  For example, assume that you want to change the HeadFontStyle property for split #2 to "2 - Bold" while leaving the headings in the default font for other splits.  Here's how you would accomplish this:

1.	Make sure SplitPropsGlobal is set to False, then change SplitIndex to 2, the split you want to change.

2.	Change the value of HeadFontStyle to "2 - Bold" and it will change the heading font only for split #2.

When you change SplitIndex to point to another split, Visual Basic will refresh its properties window to show the settings which are current for that split.

Using the Layout Editor to Configure Columns in Splits

As was mentioned briefly in the last section, the Column Properties Dialog allows you to change the characteristics of a column within one split without affecting the same column in other splits.  This section, and the reference section for the Column Properties Dialog contain details about how each operation affects columns when splits are present.

When you bring up the Column Properties Dialog, you click with the mouse over a particular column.  When you do so, TrueGrid automatically makes the split in which you clicked the current split, and the one which will be affect by changes you make when SplitPropsGlobal is False.

Of the settings available in the dialog, the following settings always apply globally to a column in all split.  This is because these characteristics are shared attributes of columns rather than being customizable on a per-split basis.  Here are the properties which are shared by columns in all splits:

1.	Column Heading (ColumnName property).  You cannot customize headings on a per-split basis, although you may hide the headings entirely, or customize their fonts.  TrueGrid's design assumes that a given column should always have the same value for ColumnName, regardless of which split is current.

2.	Column Type:  Bound, Unbound, or Calculated (ColumnType property).  You cannot make a column bound in one split, while calculated in another.  This makes application coding simpler, since no confusion results in events like Update, Validate, or UnboundFetch.

3.	Column Field Name (ColumnField property).  The field name associated with a column must be the same for the column in all splits and is a shared resource.  This allows TrueGrid to more efficiently cache field data, since it can assume that columns which appear multiple times need have data fetched only once.

4.	Column Expression (ColumnExpression property).  Like the field name, you cannot have a different expression for the same column in different splits.  Again, this makes it easier for TrueGrid to avoid recalculating column data.

5.	Column Format String (EditMask property).  The edit mask chosen for a column is shared by the column in all splits.

All other items you change in the Column Properties Dialog apply only to the column as it appears in the current split:

1.	Column Width and Ordering (ColumnWidth; ColumnOrder).  These properties specify the horizontal size of a column, and its position relative to other columns.

2.	Column Text and Heading Justification (ColumnStyle property). These settings allow you to change the text and heading justification separately for a column in each split.

3.	Column Text and Heading Font Styles (ColumnFontStyle; ColumnHeadFontStyle).  These settings specify the font to be used for column text and headings, and can be different for the same column occuring in different splits.

4.	Editability  (part of ColumnStyle).  A column can be editable in one split, while read-only in another.

5.	Visibility  (ColumnVisible property).  Although all columns must be present in all splits, they can be visible in one split while hidden in another.  The requirement that all columns be present in all splits is so that column numbering may be consistent within your programs without regard to order or split ownership.

The Column Properties Dialog also contains buttons for adding new columns and removing columns.  When adding columns,  the column will be added to all splits simultaneously and will be visible by default.  When removing columns, the column is physically removed from the layout, hence removing it from all splits.

How Locked Columns Work by Using Splits

TrueGrid simulates locked columns by creating splits with preset properties.  This section describes the locking process in detail.  Introductory information about how locked columns work is provided in Introduction to TrueGrid Splits, and in the description of the Column Properties Dialog.

Originally, splits were designed to satisfy only the need for locked columns.  However, as our prototype progressed (and additional user requests kept coming in), we realized that split capabilities would be able to provide locked column capabilities as well as host of other desirable effects.  For this reason, we have tried to define "locked columns" as a separate topic when possible, and to automate the process by including a "Locked at left" capability for easily configuring splits for this purpose.

The "Locked at left" capability can be used directly by checking the "Locked at left" checkbox in the Column Properties Dialog.  Several split features have been designed specifically to support this kind of behavior, and understanding how these properties work make it possible to harness many additional capabilities if you use the properties directly.

One important split capability which is designed to support locked columns is the "Number of columns" setting for SplitSizeMode.  Splits configured in this way always display an integral number of columns and provide the following additional benefits:

1.	Users can never see partial columns in such splits, since the split always forces its size to an integral column boundary.  This reinforces the visual integrity of columns within such splits and makes them appear as separate column areas rather than (visually) part of a split.

2.	TrueGrid allows users to resize columns within such splits and will always resize the split itself to conform to the new size.  This further reinforces the visual integrity of the column, since the user need not be aware of the presence of the split at all.

Typically, if you want to provide the appearance of locked columns, you should also set the SplitLocked property to True for that split.  This makes it impossible for the user to directly resize or remove the split at runtime.  If a split is not locked in such a fashion, and the user resizes the split itself, the "locked column" appearance will disappear since the SplitSizeMode of user-sized splits reverts to "0 - Scalable".  A thorough discussion of how SplitSizeMode works can be found under Configuring the Size of Splits.

To make it easy to create and maintain locked columns, TrueGrid makes the following assumptions about locked columns.  A column is considered a "locked column" if

...	The column is visible in a split which has SplitSizeMode set to "2 - Number of Columns", and

...	The split has its SplitLocked property set to True, and

...	The column is not visible in any other split.

If you maintain these relationships while configuring columns, then TrueGrid will continue to assume that the column is a locked column, and will enable locking and unlocking of the column using the "Locked at left" checkbox.

In addition, TrueGrid comes with three functions (TgLockColumnLeft, TgLockColumnRight, and TgUnlockColumn) which make it easy to work with such columns in your code.

Giving the User Control Over Splits

You can choose, on a per-split basis, whether or not you want your users to be able to create, resize and remove splits.  This behavior is controlled by the SplitLocked setting for a split.

Only those splits which have SplitLocked set to False will be user-configurable.  Whenever there is at least one unlocked split, the user will be able to create new splits, but only within the unlocked area.  For example, the following grid has three splits.  The left and right splits are locked, the center one is not:

Notice that there is a single split size box located to the left of the center split's horizontal scrollbar.  The user can thus create a new split within the unlocked region, such as this:

Notice also that locked splits are separated from the others by a solid vertical bar, while unlocked splits are separated by a double bar.

Selectively locking splits using SplitLocked allows you to create one or more user-configurable areas within a grid, while maintaining fixed splits elsewhere

Another capability which you may want to allow or disallow is controlled by the Configurable property.  When Configurable is True for a split (the default), the user can resize, shuffle, or remove columns.  Setting Configurable to False will disable this behavior.


Working with Splits in Your Code
 Realizing the Full Potential of Splits

 Configuring Splits At Design Time

 Working With Splits in Your Code

  How your Visual Basic code works with splits

  Creating and configuring new splits

How Your Visual Basic Code Works with Splits

When you write code in Visual Basic, you need to be aware of the setting of two important properties at all times:

1.	SplitPropsGlobal.  This property is the most important, and controls whether or not split-specific properties are applied globally to all splits, or whether they are applied only to the current split.

2.	SplitIndex.  The current split is always denoted by the value of SplitIndex.  When you access properties, the returned value is always for the split indicated by this property.  When you set a property, this index indicates which split the property will apply to.

For the most part, so long as your code is aware of these settings, and written accordingly, you should be able to easily write code for TrueGrid with a minimum concern for splits.  Some events are affected by splits, and you should consider some of these issues when coding:

1.	CellChange and ColumnChange.  These events are triggered not only when a new column becomes current, but also if a new split is selected which has a different column.  Your code may need to be aware of this.  For example, assume you wanted to change the color of the current column whenever the user selects it.  If you aren't careful to check the SplitIndex when these events are fired, then you might change the color in one split but not change it in another.

2.	SplitChange.  This event is designed specifically to inform you when the user, or your code, moves to a different split.  If you set SplitIndex, then restore it to its original value, this event won't be fired.  It will only be fired if you change SplitIndex permanently, or if your user selects a different split.

3.	Fetch event and UnboundFetch event.  Normally, you won't need to be concerned about splits in these events, since data will be fetched only once and all data characterisics (such as field name, edit mask, column heading) are not split-specific.  In fact, you should never depend upon SplitIndex in these events, since data may be fetched for a split other than the current split.

4.	FetchAttributes.  Code in this event will need to be aware of splits, since attributes are typically applied on a per-split basis.  Recall that FetchAttributes is only fired when ColumnCellAttrs is True for a column.  Since ColumnCellAttrs is a split-specific property, you can have the event fire for a column in one split but not in another.  One of the parameters to this event is the split number where the event was fired, which will not always be the same as the value of SplitIndex.  If you are applying the same attributes to all splits, then you can effectively ignore the split number passed in and always return the same values.

5.	DragCell.  The DragCell event allows you to begin a drag operation for a cell.  It can occur in any split, even if the split isn't current.  The split number where the drag began is always passed as a parameter.

Creating and Configuring New Splits

You can easily create and configure your own splits at runtime.  Doing so gives you even more control than you have at design-time over split characteristics.  Alternatively, you may want to create a simple layout at design-time, then configure the splits and per-split column properties at runtime---it's up to you.

Creating new splits at runtime is easy.  There are two methods.  First, you can simply increment the number of splits, like this:

Table1.Splits = Table1.Splits + 1

In the above case, the new split is always placed at the rightmost part of the grid.  Second, you can use the InsertSplit property to insert the new split where you want it:

Table1.InsertSplit = 1

The number you assign to InsertSplit is the location where you want the split inserted.  The example will insert a split before split number 1, or at the leftmost edge of the grid.

When new splits are created using either method, the newly created split inherits all of the characteristics and properties of the split immediately to its right, or of the final split (if there is no split to the right of the new split).  It is up to you to customize the splits.

When adding columns to the grid, you need to keep in mind that columns are always added to all splits.  It is then up to you to make the column invisible in the splits where you don't want it to appear (using ColumnVisible).

The following example illustrates many of these points.  The Table1 grid is assumed to be empty at the start.  Then, 10 columns are added, and a split is created at the left for a locked column.  Column number 3 will be the locked column and will be made invisible in the rightmost split.

Sub Form_Load ()

' Assure that split properties are not global to the grid

Table1.SplitPropsGlobal = False

' First, add the 10 columns

For i% = 1 To 10

Table1.ColumnName(i%) = "Col " & i%

Next i%

' Now, create the locked split at the left

Table1.InsertSplit = 1

' Assure that column 3 is the only one visible at

' the left, and that it is hidden at the right.  Set the SplitSizeMode

' and SplitSize to show only that one column.

Table1.SplitIndex = 1

For i% = 1 To 10

If i% <> 3 Then Table1.ColumnVisible = False

Next i%

Table1.SplitSizeMode = 2	' number of columns mode

Table1.SplitSize = 1	' 1 column

Table1.SplitLocked = True

Table1.SplitIndex = 2

Table1.ColumnVisible(3) = False

End Sub

The above methods are typical for how columns and splits are created and configured.

Once splits exist, columns can still be added.  Just remember that they will be added to all splits and you may need to reconfigure column properties on a per-split basis to get the effect you desire.


Implementing Drag and Drop using TrueGrid

  Dragging cells or rows from a grid to another control

  Dragging data onto a TrueGrid cell or row

Dragging Cells or Rows from a Grid to Another Control

Typically, implementing drag-and-drop to and from grids is a difficult proposition, mostly because you always want to drag from a particular cell or row, then drop into a particular cell or row.  Visual Basic's drag-and-drop facilities work with controls, rather than having features for working with what element of a control has been dragged.

TrueGrid has a special event, DragCell, designed to simplify the initiation of a drag operation.  DragCell is called whenever the user attempts to drag data from a cell to another location.  Your code can respond in any way you wish.  DragCell informs you of the split number, row number, and column number of the cell being dragged.  Typically, you will save the information being dragged so that it can be used when the data is dropped elsewhere.

For example, assume that you want to be able to drag a row of data elsewhere.  The following code in DragCell would start the drag operation:

Sub Table1_DragCell (Split As Integer, Row As Long, Col As Integer)

' Set the RowIndex to highlight the row (since the user may

' not have picked up the current row)

Table1.RowIndex = Row

' Save the row number so we can later find out which row was

' dragged

draggingRow = Row

' Put the control into drag mode

Table1.Drag 1

End Sub

Once this event is completed, Visual Basic takes over the drag operation (see the Visual Basic documentation for the Drag method) and will signal a drop via DragDrop in another control.  Code in the other control can then use the DragDrop method to detect the drop and use the draggingRow variable to determine which row was dragged.

Dragging Data into a TrueGrid Cell or Row

If the destination of a drag operation is a TrueGrid control, and you want to drop data into a row or cell, you need to think about the following:

1.	You may want to provide feedback for the user about which row or cell will be the target of the drop.

2.	You want to respond to the DragDrop event by actually entering the data into the new cell or row.

Often, the difficulty with implementing such operations on grids is that, given the mouse location, it is difficult to find out what cell, row, or column you are about to drop into.  TrueGrid solves this problem by providing the ColumnAtPoint, RowAtPoint and SplitAtPoint properties so you can translate a mouse coordinate into a TrueGrid location.

First, let's assume that you want to provide feedback to the user about which cell they are over.  The easiest way to do this is in the DragOver event, which is called as the mouse moves over the destination grid.  Here's how you would set the current cell pointer so that it "tracks" the dragging object:

Sub Table1_DragOver (Source As Control, X As Single, Y As Single, State As Integer)

' First, determine which cell we are pointing to

Table1.PointX = X

Table1.PointY = Y

cellRow& = Table1.RowAtPoint

cellCol% = Table1.ColumnAtPoint

' If cellRow& is -1, or cellCol% is 0, then the user is on top of

' a grid element other than a cell (such as a scrollbar).

If cellRow& = -1 Or cellCol% = 0 Then Exit Sub

' Set the current location of the grid marquee to track the operation.

Table1.RowIndex = cellRow&

Table1.ColumnIndex = cellCol%

End Sub

Once the drop occurs (sensed in your DragDrop) handler, you can either remember the original cellRow and cellCol last determined in DragOver, or recalculate the row and column using RowAtPoint and ColumnAtPoint.  Optionally, you may wish to make the split the user drops into the current split by setting SplitIndex as derived from SplitAtPoint.

TrueGrid is provided with a sample program, described under Drag and Drop Sample.  You may want to examine the source code for this sample as well.


Customizing the Behavior of Cell Editing

  Overview of cell editing

  Customizing the cell text displayed during editing

  Creating a dropdown list instead of editing cell text directly

  Changing cell contents with a single keystroke

  Creating editable calculated and unbound columns

Overview of Cell Editing

TrueGrid provides many features for customizing and controlling the way in-cell editing works.  TrueGrid's default cell editing behavior is as follows:

1.	A cell is either in display or edit mode.  The value of the EditActive property may be inspected or changed to the desired mode.  The user may enter edit mode by clicking once on the current cell.

2.	While in edit mode, the cell is displayed using the EditForeColor and EditBackColor rather than the cell color for the current cell.

3.	While editing is in progress, the value of the Modified property can be inspected to determine whether the user has made any changes to the current cell.  If Modified is False when the user exits the cell, TrueGrid takes no action except restoring the cell appearance.  The user may cancel editing by using the Escape key, or you can set Modified to False in code so that the user's edits are ignored.

4.	During editing, the Text property contains the text the user currently sees in the editing cell.  Whenever the user types, the Change event is sent to notify your application that the user has made a modification to the edited cell.  However, the Change event doesn't mean the user is completed with the process, only that they have made a single change to the edited text and are still in edit mode.

5.	If the text in the cell would exceed the boundaries of the cell, TrueGrid will "drop down" an editing box so that additional text may be seen and edited.  This behavior is controlled by the EditDropDown property, which defaults to True thus allowing such behavior.

6.	The user completes the editing process by (a) pressing Enter, (b) moving to another cell with the arrow keys.  If this occurs after modifications have been made (Modified is True), then TrueGrid first sends the Validate event so you can write code to test for the validity of the entered data.  Once validation succeeds, TrueGrid triggers the Update event to tell your application that the user data has been changed.

The following sections describe how you can make changes to this default behavior, and even replace the editing cell with your own control if you wish.

Customizing the Cell Text Displayed During Editing

When data is displayed, TrueGrid applies the Visual Basic Format String contained in the EditMask property to the displayed data.  However, when the user attempts to edit the data, the format mask is not used and the data is displayed in raw string format.  For numbers and text, this is usually what is wanted.  However, for fields such as boolean fields, the default display will be a "1" or a "0".

Often, therefore, it is desirable to change the text displayed during editing to something the user can more easily work with.  Such tasks are usually performed in the EnterEdit event.  For example, the following code in EnterEdit changes the default boolean "1" or "0" to a "Yes" or "No":

Sub Table1_EnterEdit ()

' First, make sure we are in the right column.  We use the field

' name to check so we don't depend upon column numbers.

If Table1.ColumnField(Table1.ColumnIndex) <> "Done" Then Exit Sub

' Now, translate the value to be edited so it appears more

' sensibly

Table1.Text = Format$(Table1.Text, "Yes/No")

End Sub

Although the above code changes only the column called "Done", you could just as easily have EnterEdit work with several columns (with a Select Case statement, for instance).

Once the user has completed the editing process, it is usually necessary to change the stored value back to the original form.  This is usually done in the Validate event:

Sub Table1_Validate (Row As Long, Col As Integer, Value As String)

' For the "Done" column, convert the user's response back

' to a "1" or "0".

If Table1.ColumnName(Table1.ColumnIndex) <> "Done" Then Exit Sub

If Left$(UCase$(Value)) = "Y" Then

Value = "1"

Else

Value = "0"

End If

End Sub

Notice that Validate allows you to change the value to be stored before it is written to the database.  This makes it possible to convert data in a user format to a stored format easily.

Creating a Drop-down List Instead of Editing Cell Text

Normally, TrueGrid's default text editing behavior is suffucient for a large number of applications.  In some circumstances, however, it is useful to customize the way TrueGrid performs editing.  One valuable technique is to include a drop-down combo box, or even another TrueGrid control, to allow selection from a list of common values.

This is easy to do with TrueGrid using virtually any Visual Basic control.  First, the general approach will be discussed.  Then two examples are shown.  The first example will use a standard Visual Basic list box, the second will use another TrueGrid control as the drop down.

In general, displaying a drop-down or combo instead of the standard TrueGrid editor involves the following steps:

1.	TrueGrid sends the RequestEdit event each time the user wants to edit a cell.  To override the default edit process, put code in RequestEdit to display the editing control you wish to show instead, then cancel TrueGrid's default editor by setting the Cancel parameter of RequestEdit to True.  Typically, you place the substitute editing control or drop-down on the same form as TrueGrid, but make it invisible until you need it.

2.	When RequestEdit is triggered, there are four properties you can use to determine the exact coordinates of the cell which was to be edited.  These properties are CellRectLeft, CellRectTop, CellRectWidth, and CellRectHeight.  You can use these properties to position the custom editing control or drop-down relative to the TrueGrid cell which the user clicked on.

3.	You need to put code in the drop-down or combo which completes the editing process by assigning a selected value to the ColumnText property of the original grid (the one being edited).

Example 1.  The first example is shown below.  It uses a standard Visual Basic List Box to pop up a list of pre-defined values for the current cell.

Here are the steps used to create the first example:

1.	Our sample uses a simple database which has a "Status" column we wish to edit with a pop-up list box.  We first placed the Data Control on the form and set its database properties.  Then, we placed the TrueGrid control on the form and configured its appearance.

2.	Next, we put a Visual Basic list box on the form, set its width and height, and set its Visible property to False.  You don't need to worry about its position, since that will depend upon where it is popped-up.

3.	Now, we put the following code in the RequestEdit event for Table1 (the TrueGrid grid):

Sub Table1_RequestEdit (Cancel As Integer, KeyAscii As Integer)

' If we aren't trying to edit the "Status" field, or if

' editing was initiated with a keystroke, don't use the

' popup.

    If Table1.ColumnField(Table1.ColumnIndex) <> "Status" Then Exit Sub

    If KeyAscii Then Exit Sub

' Cancel default TrueGrid editing, then position the listbox,

' make it visible, and give it focus.

    Cancel = True

    List1.Left = Table1.CellRectLeft

    List1.Top = Table1.CellRectTop + Table1.CellRectHeight

    List1.Visible = True

    List1.SetFocus

End Sub

Notice that the above code positions the list box just below the bottom border of the cell using the CellRectTop and CellRectHeight properties to calculate the position.  We give the pop-up listbox focus immediately, and when it loses focus it will always hide itself.

4.	When the user double-clicks on an item in the list, we want to replace the contents of the current TrueGrid cell with the new data.  We do this in the DblClick event for the pop-up listbox (List 1):

Sub List1_DblClick ()

' Assign the current list item to the current cell of

' the grid, then hide the popup.

    Table1.ColumnText(Table1.ColumnIndex) = List1.List(List1.ListIndex)

    List1.Visible = False

End Sub

5.	We also want to be sure the list box is hidden if another control or form gains focus:

Sub List1_LostFocus ()

List1.Visible = False

End Sub

That's all there is to it.  Now, whenever the user wants to edit cell text for the "Status" column, the pop-up allows them to select from the list of values.  The list of values can be either static (defined in Form_Load perhaps) or can be dynamically created in the RequestEdit event.  For example, the list box shown above was initialized in Form_Load like this:

Sub Form_Load ()

    List1.AddItem "In Progress"

    List1.AddItem "Pending"

    List1.AddItem "Cancelled"

    List1.AddItem "Satisfactory"

    List1.AddItem "Unsatisfactory"

    List1.AddItem "Done"

End Sub

Since any control can be used, it is possible to create a wide variety of editing effects.

Example 2.  The second example (shown below) uses another TrueGrid control as a pop-up to show the values of a field in a related database.  This example uses the standard BIBLIO.MDB database which comes with Visual Basic.  The main grid (Table1) is browsing the "Titles" table, which contains an author id column (Au_ID), but no author name.  The pop-up grid (Table2) shows the "Authors" table, which lists the author name which corresponds to each author id.

Here are the steps used to create the second example:

1.	We first placed the Data Control (Data1) on the form and configured its database properties to specify the "Titles" table of BIBLIO.MDB.  Then, we put the main grid (Table1) on the form, configured its appearance, and linked it to the Data Control.

2.	Next, we put another TrueGrid control on the form to use as a pop-up (Table2).  It is linked to a different Data Control (Data2) which is set to use the "Authors" table.  We then set its width and height, along with configuring its column appearance in the Layout Editor.  Then, we set its Visible property to False.  Again, the position doesn't matter, since that will be reset when the pop-up appears.

3.	In the RequestEdit event for the main grid (Table1), we put the following code:

Sub Table1_RequestEdit (Cancel As Integer, KeyAscii As Integer)

' If we aren't trying to edit "Au_ID", or if editing was

' initiated with a keystroke, don't use the pop-up.

    If Table1.ColumnField(Table1.ColumnIndex) <> "Au_ID" Then Exit Sub

    If KeyAscii Then Exit Sub

' Cancel default editing behavior and position the pop-up

' grid to appear just below the Table1 grid.

    Cancel = True

    Table2.Left = Table1.CellRectLeft

    Table2.Top = Table1.CellRectTop + Table1.CellRectHeight

' Locate the current value in the Data2 Recordset so that

' the grid is initially positioned to the right spot.

    Data2.Recordset.FindFirst "Au_ID = " & Table1.Text

' Make the popup visible and give it focus.

    Table2.Visible = True

    Table2.SetFocus

End Sub

The above code is almost identical to the code used for the pop-up list box, except that we position the pop-up to the current value (you could have done this with the list box as well).  Again, we give the pop-up focus initially.  When it loses focus, it will hide itself.

4.	When the user double-clicks on a row in the pop-up grid, we will replace the "Au_ID" column in Table1 with the contents of the "Au_ID" column in Table2, like this:

Sub Table2_DblClick ()

    Table1.ColumnText(Table1.ColumnIndex) = Table2.ColumnText(1)

    Table2.Visible = False

End Sub

5.	Just as in the list box example, we want to hide the pop-up grid if another control gains focus:

Sub Table2_LostFocus ()

Table2.Visible = False

End Sub

As you can see, both examples are quite similar, and performing the same kind of pop-up editing with almost any control is easy to do.

Changing Cell Contents with a Single Keystroke

The RequestEdit event is an extremely versatile way to customize the behavior of TrueGrid editing.  RequestEdit is sent before any other events occur, and gives you the opportunity to do virtually anything you want before editing begins (or to cancel editing and replace the editing process with your own, as in the last section).

With TrueGrid, edit mode may be entered in one of three ways:

1.	If the user clicks on the current cell with the mouse, editing begins using the current cell contents as the default.

2.	If the user begins typing, the typed character replaces the contents of the cell and editing begins.

3.	You can set the EditActive or Text property in your code to force editing to begin.

The RequestEdit event is sent in case 1 and 2, but not in case 3 (since TrueGrid assumes you will never want to cancel a request made from code).

You may want to differentiate a user's edit request based upon whether they used the mouse or the keyboard to start editing.  To facilitate this, one of the parameters to RequestEdit is "KeyAscii", which will be zero (0) if the user clicked on the cell with the mouse, and will be an ASCII character if the user typed a character to begin editing.

When RequestEdit is called, the ASCII character hasn't yet been placed into the current cell, so if you cancel editing in RequestEdit, the ASCII key is discarded.  This leads to an interesting technique.

Assume you have a boolean column called "Done", and you have set its EditMask to specify "Yes/No" as the display format.  Further assume that, when the user presses "Y" or "N", you want to change the cell contents immediately instead of entering edit mode.  Here's how you could accomplish this in RequestEdit:

Sub Table1_RequestEdit (Cancel As Integer, KeyAscii As Integer)

' If this isn't the "Done" column, or if they clicked with the

' mouse, then simply continue.

If KeyAscii = 0 Or Table1.ColumnField(Table1.ColumnIndex) <> "Done" Then Exit Sub

' Cancel normal editing and set the field to the proper result

' based upon KeyAscii.  Beep if they typed an invalid character.

Cancel = True

Select Case UCase$(Chr$(KeyAscii))

Case "Y"

Table1.ColumnText(Table1.ColumnIndex) = "1"

Case "N"

Table1.ColumnText(Table1.ColumnIndex) = "0"

Case Else

Beep

End Select

End If

Notice that we still allow editing with the mouse when KeyAscii is zero.  In this case, EnterEdit will be triggered next.  It is likely that the code in EnterEdit will change the "1" or "0" to a "Yes/No" value for display as well.

Creating Editable Calculated and Unbound Columns

When you create editable or calculated columns (see Using Unbound and Calculated Columns), you normally won't allow the user to edit them.  For example, imagine a pair of columns for Debit and Credit, as shown in this portion of a grid display:

Assume that there is no database field for these, but they are calculated columns which derive their value from a single "Balance" column, which is either positive or negative.  Obviously, it would be desirable to allow the user to edit these values, and cause the dependent "Balance" field to be updated automatically.

TrueGrid makes such tasks easy.  Here's the code you would put in the Update event to cause these columns to change the "Balance" column when updated:

Sub Table1_Update (Row As Long, Col As Integer, Value As String)

' When updating the Debit and Credit columns,

' update the actual field (the hidden balance column) with

' either a postitive or negative number.

If Table1.ColumnName(Col) = "Debit" Then

Table1.ColumnText(COL_BALANCE) = Val(Value)

ElseIf Table1.ColumnName(Col) = "Credit" Then

Table1.ColumnText(COL_BALANCE) = -Val(Value)

End If

End Sub

Notice that, when updating these columns, the code actually changes the value of another hidden column, COL_BALANCE (defined as a constant elsewhere).  Usually, such hidden columns are defined in the Column Properties Dialog with the Visible checkbox checked and the Preserve checkbox checked to keep the hidden column as part of the layout.  Updating a hidden column, rather than the database field, causes TrueGrid to do two things:

1.	TrueGrid will keep the value of the "Balance" column in internal storage until you move to another record, just like any other updated field, rather than writing the data to the database immediately.

2.	TrueGrid senses the change during the Update event's execution, and changes the calculated column color to the red update color automatically, giving the user the cue that the data has been changed and not written.

Another benefit can be seen when looking at the expressions used to define the Debit and Credit columns.  The Debit column has the following expression

Iif(Val(ColumnText("Balance"))>0,Val(ColumnText("Balance")),Null)

while the credit column has a similar expression:

Iif(Val(ColumnText("Balance"))<0,-Val(ColumnText("Balance")),Null)

Thus, the Debit column displays positive data (or null), and the Credit column displays negative data (or null).  Because both of these expressions depend upon the ColumnText of the TrueGrid column, our Update handler will cause both the Debit and Credit columns to be automatically refreshed.  This is because TrueGrid keeps track of the dependencies between columns and handles refresh automatically when you change values by assigning to ColumnText.


Changing Colors and Fonts on a Per-Cell Basis

  How TrueGrid applies colors and fonts to a cell

  Meaning of cell status values

  Controlling colors and fonts by cell status

  Controlling colors and fonts by cell contents

  Controlling colors and fonts using custom criteria

  Priority of colors and fonts applied to cells

How TrueGrid Applies Colors and Fonts to a Cell

TrueGrid's color and font capabilities work together to provide maximum flexibility in database capabilities.  There are several methods for applying colors and fonts to cells:

1.	The overall font and color can be selected with properties such as ForeColor, BackColor, FontBold, etc.  These properties change the overall color and font for the entire grid.

2.	Special elements of the grid can be customized.  Properties such as HeadForeColor, HeadFontStyle, SelectedForeColor, and others permit you to customize the color or font used for special purposes.

3.	Columns have a variety of color and font settings which apply to the entire column.  Properties such as ColumnForeColor, ColumnBackColor, ColumnHeadFontStyle, and others allow you to customize these colors.

4.	You can apply colors and fonts to individual cells using three different techniques (to be described in a moment), appropriate for different situations.

Most of the color and font settings are easy to use, and their effect is obvious.  The only thing you need to know about most of them are which are split-specific properties (such as ColumnForeColor) and which are global to the entire grid (such as ForeColor).

However, mastering per-cell colors requires a bit more explanation, and this section is devoted to discussing the details of the three methods you can use to apply colors to individual cells:

1.	By Status.  Each cell in the grid has a cell status which identifies the disposition of a cell (any combination of current, marked, changed, or part of highlighted row).  You can set colors which apply to any possible combination of cell status values.

2.	By Content.  You can specify a pattern (called a regular expression) which is used to perform pattern matching on cell contents.  When the contents matches the pattern, TrueGrid will automatically apply a pre-selected font or color scheme to the cell.

3.	By Custom Criteria.  Using the FetchAttributes event, you can make decisions about cell colors each time a cell is displayed.

Meaning of Cell Status Values

There are 16 separate cell status values, which indicate the disposition of a cell.  The status is a

combination of four separate conditions:

1.	Current cell.  The cell is the current cell, specified by the ColumnIndex and RowIndex properties.

2.	Part of a highlighted row marquee.  When the MarqueeStyle property indicates that the entire row is to be highlighted, cells in such rows have this additional condition set.

3.	Updated data.  The data in the cell has been updated by user modification, or setting the Text or ColumnText properties.

4.	Marked row.  The cell is part of a row marked by the user (or programmer) and displayed as such according to the setting of the SelectMode property.

The cell status is a combination of these four conditions and there are a total of 16 different cell dispositions.  During grid display, the grid determines the cell status values as data is displayed, changed, or as the current row changes.  Here, three different kinds of cells are shown with their corresponding status values.

The status value is actually a bit mask where each bit corresponds to one of the four separate conditions above.  For example, the "Cell in highlighted row" status is represented by a bit mask with the "2" bit on (hence Status=2).  The current cell when it is in a highlighted row is represented by a bit mask with the "2" and "1" bits on (hence Status=3 ... 2 + 1).  Normal cells have no bits on and are represented by a status value of zero.

The following table shows all possible status values.  The numeric status value is at the left, while individual status bit values are indicated by the legend:

C	Current cell (bit 1)

H	Part of a highlighted row marquee (bit 2)

U	Updated data in cell (bit 4)

M	Part of a marked row (bit 8)

Summary of status values:

0	Normal cell, not current, marked, updated, or part of a highlighted row.

1	C	The current cell, not marked, updated or part of a highlighted row.

2	H	Part of a highlighted row, not current, marked or updated.

3	H	C	Current cell in highlighted row, not marked or updated.

4	U	Updated cell, not current, marked, or part of a highlighed row

5	U	C	Current cell when updated, not marked or part of a highlighted row.

6	U	H	Cell updated within a highlighted row, not current or marked.

7	U	H	C	Current cell updated within a highlighted row, not marked.

8	M	Row within a marked cell, not current, updated, or part of a highlighted row.

9	M	C	Current cell within a marked row, not updated or part of a highlighted row.

10	M	H	Cell in a marked row which is also the highlighted row, not current cell and not updated.

11	M	H	C	Current cell in a marked row which is also the highlighted row, but not updated.

12	M	U	Cell within a marked row in which data has been updated, not current and not part of a highlighted row.

13	M	U	C	Current cell within a marked row in which data has been updated; not part of a highlighted row.

14	M	U	H	Cell within a marked row (which is also highlighted) in which data has been updated, but not the current cell.

15	M	U	H	C	Current cell within a marked row which is also highlighted.  Data in the cell has been updated.

Each status value is distinct, and you can set a different set of colors and fonts for each of the 16 status conditions.  That is, setting attributes for status 1 affects the current cell, but only when it is not marked, is not changed, and is not part of a highlighted row marquee.  To affect the current cell under all circumstances, you would need to set the attributes for status values 1, 3, 5, 7, 9, 11, 13, and 15.  Usually, this is not necessary since no application will have cells of all possible status values.  For example, if the marquee is set to a dotted cell, then none of the status values which indicate a row marquee condition will ever be encountered.

The constants GFS_CURCELL, GFS_HIGHROW, GFS_CHANGED, and GFS_SELECTED are defined in TGCONST.TXT for you to use in your code instead of hard-coded numeric values.

Controlling Colors and Fonts By Cell Status

Each cell in the TrueGrid display has a status value associated with it (described in the last section).  During normal use, cell status values are constantly changing.  For example, as the marquee is moved over the data, the status of the cell beneath the marquee changes to reflect its new disposition.

For each unique status combination, you can set a foreground color, background color, and font style to be used for cells of that status.  When a cell is assigned its status, TrueGrid checks to see if any color or font overrides are defined for that cell, and applies those attributes to the cell when it is displayed.

In order to specify the color and font for a cell, you first need to set three parameter properties:

1.	ParamForeColor specifies the foreground color.  You can set this value to INHERIT_COLOR so that no foreground color will be associated with the status (to be supplied later).

2.	ParamBackColor specifies the background color, or you can set it to INHERIT_COLOR so that this parameter will be ignored.

3.	ParamFontStyle specifies the font style to be used for the status value.

Setting the above parameters places them in a "holding area" so that they can be used by properties which actually change the grid behavior.  By themselves, they have no effect.

Next, you use SetStatusAttr to specify the status value which should use the parameters just set.  For example, to set the current cell so that it is white-on-blue, with the default font:

Table1.ParamForeColor = WHITE

Table1.ParamBackColor = BLUE

Table1.ParamFontStyle = INHERIT_FONT

Table1.SetStatusAttr = 1	' GFS_CURCELL

Now, the current cell will always appear in white-on-blue.  However, it is important to realize that this setting applies only to cells which have the exact status of 1.  Thus, cells which are current but also updated (Status=5) will not be white-on-blue unless you also set the status for that type of cell.

Although this method is very flexible, it also means that more code needs to be written for some common cases.  To simplify this, two utility functions (TgSetMarqueeColor and TgSetCurCellColor) are provided in TGUTILS.BAS to handle more common settings for statuses.

Any change to the set of status attributes will take effect immediately.   Thus, status attributes can be used for interactive effects as well as the overall characteristics of the grid.

SetStatusAttr is a split-specific property and you can set a different set of status values for each split.  In addition, you can specify colors and fonts for cells which match a status only in particular columns.  This is done using ColumnSetStatusAttr, which works identically to SetStatusAttr, but will apply only to cells within the given column.

Controlling Colors and Fonts by Cell Contents

You can tell TrueGrid to automatically apply colors and fonts to particular cells, based upon their displayed contents.  To do so, you provide a pattern (in the form of a regular expression) which TrueGrid tests against the displayed value of each cell.

Like the status settings (described above), you need to set the parameter properties to specify the foreground color (ParamForeColor), background color (ParamBackColor), and font style (ParamFontStyle) to be used for cells which match the pattern.  In addition, for pattern matching purposes, you can also set the ParamStatus parmeter to a valid status in order to restrict the match only to cells which have the particular status.  If ParamStatus is set to -1, then the status will be ignored (any match will have the color and font applied, regardless of status).

Here's an example.  Assume that you want any cell which contains the word "overdue" to appear in red.  You would execute the following statments when you configure your grid (in Form_Load for instance):

' Set parameters so that the cell foreground color is red

Table1.ParamForeColor = RED

Table1.ParamBackColor = INHERIT_COLOR

Table1.ParamFontStyle = INHERIT_FONT

Table1.ParamStatus = -1

' Add a pattern to the grid pattern matching table

Table1.AddRegexAttr = "overdue"

Now, TrueGrid will dynamically change the foreground color of any cell which contains the word "overdue" so that it appears with a foreground color which is red.  Any other color and font settings for the cell will be unaffected.

You can add as many patterns as you wish to the pattern table.  TrueGrid will test for the patterns in the order you provided them and will act upon the first match.  Therefore, you should put more "specific" matches first.

When you add patterns, or when cell contents changes, TrueGrid automatically reassesses the status of cells and reassigns their colors and fonts.  Once you set up pattern matching table, TrueGrid takes much of the work out of maintaining the proper appearance for your grid.

The AddRegexAttr property adds to the list of patterns for all columns.  However, you can add patterns which have an effect only on a particular column using the ColumnAddRegexAttr property.  This property works just like AddRegexAttr, but keeps a list of patterns which are valid only for the specified column.

You can test to see if any patterns are present for the grid, or for a column, by checking the value of HasRegexAttr and ColumnHasRegexAttr.  These properties return True if there are any patterns present for the grid or the column and return False if there are no patterns defined.  By setting either of these properties to False, you can remove all patterns for the grid or for the column.

One common use for pattern-based attribute settings are for displaying negative numbers is red.  Since this is so common, a special utility function, TgSetNegativeColColor allows you to specify a color to be used for negative numbers within a column.  It automatically sets the proper pattern to match negatives within a given column.

One good idea for pattern matching is to perform "visual queries" where cells matching a certain pattern are highlighted with a color or font style.  For example, you may want to have all cells containing a person's name appear in italics when they are using your program.  Since pattern matching is very fast, you can dynamically change the pattern table to create different effects, or you can give your users the ability to do a string search by highlighting cells which contain a user-typed string.

For more information about specifying patterns, see the section entitled Introduction to Regular Expressions.

Controlling Colors and Fonts Using Custom Criteria

You may discover that neither the per-cell status attributes nor the pattern matching attributes provided with TrueGrid will satisfy your needs.  When all else fails, TrueGrid provides a very flexible technique for applying colors and fonts to cells based upon the FetchAttributes event.

You enable FetchAttributes by setting a columns ColumnCellAttrs property to True.  After doing this, TrueGrid will query your program whenever it needs to know what the color and font should be for a cell.  This allows you a great deal of flexibility, since you can decide upon the color and font using virtually any critieria you choose.

For example, assume that you want a cell containing the field "Description" to appear in red if another column (containing the "Priority") is less than the value 3.  Here's how to do it:

1.	First, in your Form_Load, make sure you set up the "Description" column to use FetchAttributes:

Sub Form_Load ()

' Get the column number

desccol% = TgFindColumn(Table1, "Description")

Table1.ColumnCellAttrs(desccol%) = True

End Sub

2.	Now, in your FetchAttributes event, test the value of the priority column to determine the cell attributes for the description column:

Sub Table1_FetchAttributes (Status As Integer, Split As Integer, Row As Long, Col As Integer, FgColor As Long, BgColor As Long, FontStyle As Integer)

' We don't need to check to see what column we're in, since the

' description column is the only one which has ColumnCellAttrs

' set to True.

pricolumn% = TgFindColumn(Table1, "Priority")

If Val(Table1.ColumnText(pricolumn%)) <= 2 Then

FgColor = RED

End If

End Sub

Only those parameters which you change (such as FgColor above) will have an effect on the cell.  The other parameters are set so that the colors and fonts are inherited from whatever characteristics the cell would normally have after all other font styles, colors, and attributes are applied.

Notice that TrueGrid includes the cell status as the first argument to the event.  This is done so that you can test yourself to see whether the cell is current, part of a highlighted row, updated, or marked.  You can then adjust your color settings accordingly (if the status of the cell matters in your application).

Using FetchAttributes is less efficient than using status-based or pattern-based color schemes.  TrueGrid will need to trigger FetchAttributes in a wide variety of circumstances (such as when a new cell becomes current).  If you keep the code in your FetchAttributes event as brief and efficient as possible, it should have minimal effect on display speed (if any).

Priority of Colors and Fonts Applied to Cells

TrueGrid has many settings which affect the color and font of a cell.  In some circumstances it may be necessary to know exactly which colors and fonts take priority over others.

For each cell displayed, TrueGrid applies colors and fonts in the following order:

1.	Overall Settings.  The lowest priority colors are those set for the entire grid, such as ForeColor, BackColor, FontBold, FontItalic, FontUnderline, etc.  If no other colors are present of a higher priority, TrueGrid uses these.

2.	Column Settings.  The properties ColumnForeColor, ColumnBackColor, and ColumnFontStyle are applied to the cell next.  It overrides any settings present for the grid as a whole.

3.	Selected Color Settings.  Next, TrueGrid checks to see if the row is selected and uses the SelectedForeColor and SelectedBackColor for the cell if it is.  These colors override any color settings for the column, or for the overall grid.

4.	Global Regular Expression.  TrueGrid next checks to see if the cell contents matches a pattern added with AddRegexAttr.  If it does, TrueGrid uses the attrbutes defined for the pattern instead of a selected color, column color, or overall grid attribute.

5.	Global Cell Status.  Next, TrueGrid checks for a per-status setting for the column (such as a current cell color set with SetStatusAttr).  TrueGrid will use the settings for the cell's status (if present) instead of any of the above attributes.

6.	Column Regular Expression.  TrueGrid next checks the patterns defined for the column using ColumnAddRegexAttr.  If there is a pattern match for the cell, then TrueGrid uses these attributes instead of any of those described above.

7.	Column Status.  Any per-status attributes set for the column using ColumnSetStatusAttr override all other color settings above and are applied to the cell next.

8.	FetchAttributes Settings.  Finally, if ColumnCellAttrs is True for the column, TrueGrid queries your program using FetchAttributes.  If your program changes any of the characteristics for the cell, these settings will override all other settings and have the highest priority.

Although it would seem that TrueGrid has a lot of work to do for each cell, the actual process used by TrueGrid is much more efficient than this list would imply.  TrueGrid will apply only those attributes which "fall-through" the above list, and will apply them to the cell only once rather than actually testing each of these situations.


Regular Expression Reference Material

  Introduction to TrueGrid regular expressions

  Syntax of TrueGrid regular expressions

  Commonly used regular expressions

Introduction to TrueGrid Regular Expressions

TrueGrid uses regular expressions to allow efficient customization of cell attributes based upon their contents.  A regular expression is a pattern which is used to match displayed text within cells.  The AddRegexAttr and ColumnAddRegexAttr properties both require regular expressions to indicate which cells match, and subsequently which attributes will be applied to cells.  Regular expression pattern matches can also be used to highlight cells for purposes of displaying the results of string searches or other query-like behavior where cell color of font can be a valuable cue to the user.

Visual Basic supports a kind of regular expression via the Like operator, but TrueGrid supports a more complete Unix-like regular expression syntax which is incompatible with the Visual Basic form.  However, the concepts are similar, and this section will provide an overview of how TrueGrid's regular expressions work, and what the patterns mean.

Regular expressions can be simple strings, such as "overdue" which will match the word "overdue" anywhere within the cell text.   They can also be more complicated.  For example, the regular expression "[0-9$,]+\.[0-9][0-9]" will match any string containing a dollar amount with two decimal positions such as "$123.00" or "$9,345.66".  As you can see, regular expressions offer powerful potential for selecting cells based upon ther contents.

The following section describes the detailed syntax of regular expressions.  For details about how they are used, see Changing Colors and Fonts on a Per-Cell Basis.

Syntax of TrueGrid Regular Expressions

Regular expressions allow sophisticated pattern matching on cell contents.  The regular expressions supported by TrueGrid are a subset of standard Unix regular expressions syntax and are not compatible with the regular expressions used in the Visual Basic Like operator.

A regular expression consists of a string of characters.  Some characters (described in a moment) have special behavior.  Any other character matches itself and is not case-sensitive.  You can remove the special meaning of regular expression characters by prefixing the character with a backslash (\).

The following regular expression special characters are supported:

p*	Any pattern followed by an asterisk matches zero or more occurrences of that pattern.  For example, "ab*c" matches "ac", "abc", "abbcy" (partial match).

p+	Any pattern followed by a plus sign matches one or more occurrences of that pattern.  For example, "ab+c" matches "abc" and "abbcy", but not "ac".

[list]	A list of characters (case-sensitive) enclosed in brackets matches any one of those characters in the given position in the string.  Ranges can be used.  "[abcd]" matches "a", "b", "c", "d".  The list "[a-d]" is equivalent.  Multiple ranges can be used.  For example, "[A-Za-z0-9]" matches any letter or digit.  This pattern can be combined with * and +: "[A-Z]+" matches a sequence of one or more uppercase letters.

[^list]	If a list starts with a caret, it matches any character except those specified in the list.

. (period)	The period represents any single character.

^p	A caret at the beginning of the pattern forces the pattern to occur at the start of a field.  Otherwise, the pattern can start anywhere in a field.

p$	A dollar sign at the end of the pattern forces the pattern to occur at the end of a field.  Otherwise, the pattern can end anywhere.

\c	Any character preceded by a backslash represents itself, unless enclosed in brackets, in which case the backslash is taken literally.

Any other character represents itself and will be compared without regard to case.

Commonly Used Regular Expressions

Here are some regular expressions which may be useful when performing pattern matching on TrueGrid Cells.  The patterns here are enclosed in quotes, although the quotes are not part of the pattern:

"^ *-"	This pattern matches any cell which starts with a minus sign, optionally preceded by blanks, such as "-123", "  -123" (and also " -hello")..

"^ *(.+) *$"	This pattern matches any cell whose contents is enclosed in parenthesis, such as "(123.00)",  or "  (12)   ".

"[$,0-9]+\.*[0-9]*"
This pattern matches any dollar amount, with optional decimal positions, such as "$123", "  $1,334.67".

"\-*[0-9]+\.*[0-9]*"
This pattern matches any numeric string, with optional decimal positions and an optional leading minus sign.  Matches include "-23", "12.55", "  -7.88099".

"[0-9]+[nrts][tdh]"
This pattern will match any ordinal number in a string, such as "1st", "23rd", "16th".


Column Properties Dialog with Split-Specific Highlighting


Grid Properties Index
 TrueGrid Properties

TrueGrid Properties are used to define a state or characteristic of the grid control.  Properties can be set at design time via the properties window.  The contents of the properties can be referenced, and usually modified at runtime also.  Here is the list of the grid control properties:

Standard Properties

A

About

Active

AddRegexAttr

AllowArrows

AllowTabs

B

BookmarkCount

BookmarkList

BottomRow

BookmarkCount

BookmarkList

BottomRow

C

CellRectHeight

CellRectLeft

CellRectTop

CellRectWidth

ColumnAddRegexAttr

ColumnAtPoint

ColumnBackColor

ColumnButton

ColumnCellAttr

ColumnChanged

ColumnComboMaxItems

ColumnExpression

ColumnFetchMargins

ColumnField

ColumnFontStyle

ColumnForeColor

ColumnHasRegexAttr

ColumnHeadFontStyle

ColumnIndex

ColumnName

ColumnOrder

ColumnRectLeft

ColumnRectWidth

Columns

ColumnSetStatusAttr

ColumnSize

ColumnStyle

ColumnSum

ColumnSumEnable

ColumnText

ColumnType

ColumnVertScroll

ColumnVisible

ColumnWidth

ColumnWordWrap

Configurable

CurCellVisible

D

DataChanged

DataMode

DataSource

DataSourceHwnd

E - F

Editable

EditActive

EditBackColor

EditDropDown

EditForeColor

EditMask

ExposeCellMode

ExtendRightCol

FetchMode

G - H

HasRegexAttr

HeadBackColor

HeadFontStyle

HeadForeColor

HeadingHeight

Headings

HorzColor

HorzLines

HorzScrollbar

HwndEdit

I - K

InactiveBackColor

InactiveForeColor

InsertSplit

L

Layout

LayoutIndex

LeftColumn

LinesPerRow

M - O

MarqueeStyle

MarqueeUnique

Modified

P - Q

ParamBackColor

ParamFontStyle

ParamForeColor

ParamStatus

Picture

PointX

PointY

R

ReferenceRow

RefreshColumn

RefreshRow

RemoveSplit

RightColumn

RowAtPoint

RowIndex

Rows

S

SelectedBackColor

SelectedForeColor

SelectMode

SelectZoneWidth

SelLength

SelStart

SelText

SetStatusAttr

SplitEditable

SplitGroup

SplitIndex

SplitLocked

SplitPropsGlobal

Splits

SplitSelectable

SplitSize

SplitSizeMode

SplitTabMode

T - U

TabCapture

Text

TopRow

V - Z

Version

VertColor

VertLines

VertScrollbar

VlistColumn

VlistCount

VlistData

VlistDefault

VlistPicture

VlistStyle

VlistText

WrapCellPointer


Grid Events Index
 TrueGrid Events

The following events can be used to respond to grid activity and customize the behavior of various aspects of TrueGrid's operation

Append

CellChange

Change

CheckRows

ClickButton

ColumnChange

ColumnSumChange

ComboSelect

DragCell

EnterEdit

ExitEdit

Fetch

FetchAttributes

FetchMargins

LayoutChange

LeftColChange

MarkChange

QueryMark

RequestEdit

RowChange

SplitChange

TopRowChange

UnboundFetch

Update

Validate

ValidateError

Standard Events


Grid About Property

See Also	Group

Usage	Available only at design time

Decription	Use this property to check the TrueGrid version at design time.  Click on the ellipse in the properties window to bring up information about TrueGrid.

The cow's head seen in the VBX picture is the official symbol of TrueGrid.  It was brought in off the range by a covered wagon.  For those patient or clever enough this arduous journey can be recreated.


Grid Active Property

See Also	Example	Group

Usage	grid.Active = boolean

Read/Write at design time and run time.

Property is global

Description	This property determines if the grid will respond to changes made to the database using other database functions (either in code, or via the Data Control or other bound controls).  When True (the default), the grid will refresh itself automatically when the record pointer is moved (using commands like Data1.Recordset.MoveNext) or when records are added, deleted, updated, sorted, or when selections are made using SQL statments.  When set to False, the grid will not refresh itself automatically.

Normally, you should leave this property set to True, and you should rarely need to change it.  Even when Active is set to True, the grid automatically suppresses updates to the grid while your program code is executing.   Thus, you can perform any number of complex operations, and the grid will remain unchanged until your program becomes idle or until you send the Refresh method to the grid.  Even when sending a Refresh method the grid only checks for new attributes that have been applied to it, it does not refresh data from the database.  Because of this automatic behavior, you should rarely need to use the Active property.

One case where it is useful to set Active to False is when you are displaying a modal dialog and a grid is present elsewhere on the screen.  For example, if you were to create a modal dialog which will calculate totals for columns, the grid would normally track the record you are currently positioned to, which may be undesirable.  In such circumstances, you might want to set Active to False so it remains dormant until the dialog completes its task.

This behavior is different from bound text boxes, which update instantly even while your program is running.

Valid only in database mode, not used in callback mode.

When set to False, the grid can still be used interactively.  However, the data displayed may not be the actual data in the database.  This situation can be very confusing to the user and should be avoided.  As soon as Active is set to True, the grid will refresh itself if necessary, then remain in sync with the database thereafter.


Grid AddRegexAttr Property

See Also	Example	Group

Usage	grid.AddRegexAttr = regularexpression

Write only at run time.  Not available at design time.

Split-specific property

Description	This property allows you to control the color of a cell based on the cell contents by matching the specified regular expression with the cell contents at run time.  Before this property is set to the specified regular expression, the programmer must also set four additional properties:  ParamStatus, ParamBackColor, ParamForeColor, and ParamFontStyle,

The regular expression and the ParamStatus determine the conditions that must be satisfied before the color attributes will be applied to a given cell - the cell contents must match with the regular expression and the cell status must match with ParamStatus.  If these conditions are satisfied, then ParamBackColor, ParamForeColor, and ParamFontStyle will be applied when displaying the cell.

Everytime this property is set, the regular expression and the ParamStatus conditions are added to the list of existing conditions.  Hence, by repeated use of this property it is possible to set up multiple conditions to affect the display appearance of the grid.

If one of the Param properties is not set before calling AddRegexAttr it will use the previous setting for that property.  If the Param property has never been set then it will inherit the existing grid property.  It is best to explicitly set all four Param properties before each call so that you don1t get unexpected behavior (unless of course that is the behavior you want).

The grid applies color using an attribute precedence scheme.  Attribute precedence is the order in which color and font properties are applied to the grid.  The precedence for AddRegexAttr is four (4).

This property can only be written to and cannot be read.  If you attempt to read this property at run-time an error will occur.


Grid AllowArrows Property

See Also	Example	Group

Usage	grid.AllowArrows = boolean

Read/Write at run time and design time.

Property is global

Description	If False, the left and right arrow keys will move focus from control to control and cannot be used to move between cells.

If True (the default), then you can use the arrow keys to move from cell to cell within the same row.  You cannot use the arrow keys to move out of the grid control when this property is set to True.  If the WrapCellPointer property is also set to True then the arrow keys will wrap around rows and you can navigate the entire grid using the arrow keys


Grid AllowTabs Property

See Also	Example	Group

Usage	grid.AllowTabs = boolean

Read/Write at run time and design time.

Property is global

Description	If False, the tab key will move focus from control to control and cannot be used to move between cells.

If True (the default), then you can use the tab key to move from cell to cell within the same row.

Whether the tab key will exit the grid at the end (or beginning) of a row is determined entirely by the TabCapture property.  If TabCapture is False, then the tab key will always exit the grid when pressed at the end (or the beginning) of a row.  If TabCapture is True, then user cannot use the tab key to exit the grid.


Grid BookmarkCount Property

See Also	Example	Group

Usage	grid.BookmarkCount = integerexpression

Read/Write at run time.  Not available at design time.

Property is global

Description	This property contains the number of rows currently selected.  Only rows selected by the user using the checkmark cursor, or added to the BookmarkList using code are considiered "selected".  Row selection is controlled by the setting of the SelectMode property.

As the user selects rows, BookmarkCount increases to reflect the current selection size.  Adding selected bookmarks to the BookmarkList will also cause the BookmarkCount to increase.

You can only set the value of BookmarkCount to zero (0), which clears the BookmarkList and all selected rows on the grid.  Any other value is illegal.


Grid BookmarkList Property

See Also	Example	Group

Usage	grid.BookmarkList(index) = bookmarkstring

Read/Write at run time.  Not available at design time.

Property is global

Description	The BookmarkList property contains a list of bookmarks for all selected grid rows.  When the user selects rows, their bookmarks are automatically added to the BookmarkList and BookmarkCount is automatically incremented.  The ability to select rows is controlled by the SelectMode property.

The index value is zero-based and has a maximum value of one less than the current value of BookmarkCount.

All bookmarks in the list can be read, but you can only add bookmarks to the end of the list.  You cannot update an existing bookmark with a new value.  You can remove an individual bookmark (and automatically unhighlight it in the grid) if you know the bookmark index by setting the BookmarkList(index) value to an empty string.  The BookmarkCount will be decreased by one, and any bookmarks higher in the list will be shifted down by one (filling the slot vacated by the deleted bookmark).


Grid BottomRow Property

See Also	Example	Group

Usage	numericresult = grid.BottomRow

Read-only at run time.  Not available at design time.

Split-specific property

Description	This property denotes the one-based index of the bottommost grid row.  The difference between this property and the TopRow property, plus one (1), is the number of records currently visible in the grid.  If there are fewer rows of data than screen rows, BottomRow will refer to the bottom row of data, not the bottom screen row.

To the grid, the term row number refers to the row within the overall set of data being browsed, rather than the screen row number.  Whether in callback or database mode, row one (1) does not refer to the topmost screen row of the displayed grid, but refers to the first row of data.  A grid may contain thousands or even millions of rows.


Grid CellRectHeight Property

See Also	Example	Group

Usage	width = grid.CellRectHeight

Read-only at run time.  Not available at design time.

Split-specific property

Description	If the current cell is visible, this property returns the height of the current cell (using the scale units of the control's container).  If the current cell is not visible, this property returns zero (0)

This property and other cell and column dimension and location properties enable you to easily implement some useful location-specific features.  Examples might be drag and drop, popping up balloon help, or other controls such as a combo box or your own edit window.


Grid CellRectLeft Property

See Also	Example	Group

Usage	width = grid.CellRectLeft

Read-only at run time.  Not available at design time.

Split-specific property

Description	If the current cell is visible, this property returns the location of the left boundary of the current cell (using the scale units of the control's container).  If the current cell is not visible, this property returns zero (0).

This property and other cell and column dimension and location properties enable you to easily implement some useful location-specific features.  Examples might be drag and drop, popping up balloon help, or other controls such as a combo box or your own edit window.


Grid CellRectTop Property

See Also	Example	Group

Usage	width = grid.CellRectTop

Read-only at run time.  Not available at design time.

Split-specific property

Description	If the current cell is visible, this property returns the location of the top boundary of the current cell (using the scale units of the control's container).  If the current cell is not visible, this property returns zero (0).

This property and other cell and column dimension and location properties enable you to easily implement some useful location-specific features.  Examples might be drag and drop, popping up balloon help, or other controls such as a combo box or your own edit window.


Grid CellRectWidth Property

See Also	Example	Group

Usage	width = grid.CellRectWidth

Read-only at run time.  Not available at design time.

Split-specific property

Description	If the current cell is visible, this property returns the width of the current cell (using the scale units of the control's container).  If the current cell is not visible, this property returns zero (0)

This property and other cell and column dimension and location properties enable you to easily implement some useful location-specific features.  Examples might be drag and drop, popping up balloon help, or other controls such as a combo box or your own edit window.


Grid ColumnAddRegexAttr Property

See Also	Example	Group

Usage	grid.ColumnAddRegexAttr(column) = regularexpression

Write only at run time.  Not available at design time.

Split-specific property

Description	This property allows you to control the color of a cell in the specified column based on the cell contents by matching the specified regular expression with the cell contents at run time.  Before this property is set to the specified regular expression, the programmer must also set four additional properties:  ParamStatus, ParamBackColor, ParamForeColor, and ParamFontStyle,

The regular expression and the ParamStatus determine the conditions that must be satisfied before the color attributes will be applied to a given cell in the specified column - the cell contents must match with the regular expression and the cell status must match with ParamStatus.  If these conditions are satisfied, then ParamBackColor, ParamForeColor, and ParamFontStyle will be applied when displaying the cell.

Every time this property is set, the regular expression and the ParamStatus conditions are added to the list of existing conditions.  Hence, by repeated use of this property it is possible to set up multiple conditions to affect the display appearance of the grid.

If one of the Param properties is not set before calling ColumnAddRegexAttr it will use the previous setting for that property.  If the Param property has never been set then it will inherit the existing grid property.  It is best to explicitly set all four Param properties before each call so that you dont get unexpected behavior .

The grid applies color using an attribute precedence scheme.  Attribute precedence is the order in which color and font properties are applied to the grid.  The precedence for ColumnAddRegexAttr is six (6).

This property can only be written to and cannot be read.  If you attempt to read this property at run-time an error will occur.


Grid ColumnAtPoint Property

See Also	Example	Group

Usage	integervar = grid.ColumnAtPoint

Read-only at run time.  Not available at design time.

Property is global

Description	Returns the column which is beneath the point specified by PointX and PointY.  If the point is not over a grid column, this property returns zero.

This property and other cell and column dimension and location properties enable you to easily implement some useful location-specific features.  Examples might be drag and drop, popping up balloon help, or other controls such as a combo box or your own edit window.


Grid ColumnBackColor Property

See Also	Example	Group

Usage	grid.ColumnBackColor(column) = colorvalue

Read/Write at run time.  Not available at design time.

Split-specific property

Description	This property denotes the color of the specified column's background.  If this setting is left to the default of negative one (-1) then the ColumnBackColor will inherit the grid's BackColor setting.  Set this property the same as you would set any other color property.

The grid applies color using an attribute precedence scheme.  Attribute precedence is the order in which color and font properties are applied to the grid.  The precedence for ColumnBackColor is two (2).


Grid ColumnButton Property

See Also	Example	Group

Usage	grid.ColumnButton(column) = boolean

Read/Write at run time.  Not available at design time.

Split-specific property

Description	This property allows you to control whether a button will be displayed at the upper right hand corner of the current cell at runtime.  Default value for this property is false.

In the Fields Values... dialog, if you choose "as Combo Box" as the display values (see the Using the built-in combo box section above), the ColumnButton property for the specified column will be set to true.  If you choose "as Text" or "as Radio Buttons" as the display values, the ColumnButton property for the specified column will be set to false.

You generally display the button if you want to drop down a Visual Basic control (such as the built-in combo box or a bound list box) for editing or data entry.  When the button in the current cell is clicked, the ClickButton event will be fired.  You can then write code to drop down the desired control from the cell.


Grid ColumnComboMaxItems Property

See Also	Example	Group

Usage	grid.ColumnComboMaxItems(column) = integerexpression

Read/Write at run time.  Not available at design time.

Property is global

Description	This property allows you to control the maximum number of items to be displayed in the built-in combo box.  Default value for this property is five (5).

In the Fields Values... dialog, if you choose "as Combo Box" as the display values, the built-in combo list will contain all the value items defined in the value list.  At runtime, if the number of value items is less than or equal to ColumnComboMaxItems, all the value items will be displayed in the drop down list.  If the number of value items exceeds ColumnComboMaxItems, only ColumnComboMaxItems items will be displayed in the drop down list.  A scroll bar will appear at the right hand edge of the drop down list to allow users to scroll the list to review all the value items.


Grid ColumnCellAttrs Property

See Also	Example	Group

Usage	grid.ColumnCellAttrs(column) = boolean

Read/Write at run time.  Not available at design time.

Property is global

Description	If this property is set to True then the FetchAttributes event will be called to determine the cell color of the specified column.  By default this value is False and FetchAttributes is not called for the specified column.

Set this value to True when you need to do complex operations on a particular column that can only be done using the FetchAttributes event.  For example if you want to test a range of values, or compare a value in this column to some complex expressions and then set display attributes accordingly.

The grid applies color using an attribute precedence scheme.  Attribute precedence is the order in which color and font properties are applied to the grid.  The precedence for ColumnCellAttrs is eight (8).


Grid ColumnChanged Property

See Also	Example	Group

Usage	boolean = grid.ColumnChanged(column)

Read-only at run time.  Not available at design time.

Property is global

Description	The ColumnChanged property returns True if the data in the current row of the specified column has been edited by the user, but has not yet been updated to the database.  This happens if a cell has been edited, but the current row position hasn't yet been moved, or if it is about to be moved and a Validate handler is executing.

Cells which have been changed, but not yet updated, appear in red (by default) in the grid until they are written to the database.

The DataChanged property is always True when one or more columns have a True value for their ColumnChanged property.  Setting DataChanged to False will change all ColumnChanged values to False as well.  You cannot set the ColumnChanged property to False at run time.

This property is especially useful in Data Control Validate handlers, and used in conjunction with the ColumnText property.


Grid ColumnExpression
 Grid ColumnExpression Property

See Also	Example	Group

Usage	grid.ColumnExpression(column) = stringexpression

Read/Write at design time and run time.

Property is global

Description	If the ColumnType property is set to 2 - Calculated, TrueGrid will evaluate the Visual Basic expression as defined in the ColumnExpression property and displays the result.  If this property is set at run-time the grid automatically recalculates the expression and refreshes the display.  This feature enables programmers to define calculated columns without writing code.  The expression string supports the following syntax:

1.	All symbols in the expression including constants, operators, fieldnames and function names are not case sensitive.

2.	The following Visual Basic constants are supported:

Null

True, False

Numeric constants, e.g., 1, 1.45, 1e3

String constants, e.g., "abc"

Date constants, e.g., #1/1/1900#, but time is not supported, e.g., #1/1/1900 1:00am# is not supported.

3.	All Visual Basic operators listed in P.647 of the Visual Basic 3.0 Language Reference manual (except "Like" and "Is") are supported.

4.	Fieldnames are supported, e.g., lastname, [publisher comment].

5.	Thirty-seven (37) Visual Basic functions are supported.  Note: that our versions of date functions DO NOT support time.

6.	A special function, ColumnText(Col or Name), or the short hand version Ct(Col or Name), is supported so that programmers can refer to the contents of other field columns or even other calculated columns.  ColumnText takes either the column number (Col) or a name string (Name) as argument.  When the Name string is used, TrueGrid will first search (non-case-sensitive) for a fieldname that matches with Name; if it fails, then it will search for a column heading name that matches with Name.

If a cell has been edited by the user but has not been updated to the database (e.g., user changes a cell but stays in the same record row), ColumnText() will reflect the changed value in the cell.  Programmers should use the fieldname to refer to the unchanged value in the database.

If an expression refers to another calculated column, TrueGrid will automatically resolve the dependency and calculation order.  When assigning to ColumnExpression, TrueGrid checks for syntax errors.  A syntax error will trigger a Visual Basic error which can be trapped with the On Error function and the old expression will remain intact.

Great care has been taken to assure that ColumnExpression will give the same results as similar expressions in Visual Basic code.


Visual Basic Operators

The following table lists all Visual Basic operators that are supported by the TrueGrid ColumnExpression.  Arithmetic operators are evaluated first, comparison next, and logical last.  All comparison operators have equal precedence and will be evaluated in the left-to-right order in which they appear.  Arithmetic and logical operators are evaluated in the order of precedence shown below:

Arithmetic	Comparison	Logical
Exponentiation (^)	Equality (=)	Not
Negation (-)	Inequality (<>)	And
Multiplication and division (*, /)	Less than (<)	Or
Integer division (\)	Greater than (>)	Xor
Modulo arithmetic (Mod)	Less than or equal to (<=)	Eqv
Addition and subtraction (+, -)	Greater than or equal to (>=)	Imp
String Concatenation (&)


Visual Basic Functions

The following Visual Basic functions are supported by the TrueGrid ColumnExpression.  Please refer to the Visual Basic 3.0 Help Files or the Language Reference Manual for a complete description of the functions.

Abs	Fix	Now
Asc	Iif	Right or Right$
CCur	Int	RTrim or RTrim$
CDbl	IsDate	Sgn
Chr or Chr$	IsNull	Space or Space$
CvDate	IsNumeric	Sqr
DateAdd	LCase or LCase$	Str or Str$
DateDiff	Left or Left$	String or String$
DatePart	Len	Trim or Trim$
DateSerial	Log	UCase or UCase$
DateValue	LTrim or LTrim$	Val
Day	Mid or Mid$	Weekday
Exp	Month	Year


Grid ColumnFetchMargins Property

See Also	Example	Group

Usage	grid.ColumnFetchMargins(column) = boolean

Read/Write at run time.  Not available at design time.

Split-specific property

Description	If True, the FetchMargins event will be called whenever the grid displays cells in the specified column.  Defaults to False for all columns.

Using this property, it is possible to indent the cell text for one or more cells within a specified column  For example you can indent branch offices from main offices when displaying them in the same column.


Grid ColumnField Property

See Also	Example	Group

Usage	grid.ColumnField(column) = stringexpression

Read/Write at run time.  Access via Layout Editor at design time.

Property is global

Description	This property holds the database field name for a grid column.  It will be set automatically if the Layout Editor is chosen while a valid DataSource is present at design-time.  It is not needed in callback mode but programmer can use this property to store additional information.

This property is useful for adding new columns to an existing grid layout when the structure of its associated database has been modified.

When assigning a value to this property, you can use a column index one greater than the maximum number of columns currently contained in the grid (returned by the Columns property).  The grid will create a new column and automatically increase the column count.


Grid ColumnFontStyle Property

See Also	Example	Group

Usage	grid.ColumnFontStyle(column) = numericexpression

Read\Write at run and design time.

Split-specific property

Values	0 - Inherit (default)

1 - Normal

2 - Bold

3 - Italic

4 - Bold + Italic

5 - Underline

6 - Underline + Bold

7 - Underline + Italic

8 - Underline + Bold + Italic

Description	This property allows you to set the Font characteristics for the specified column.  The default setting, 0 - Inherit, means that the column will inherit the Font characteristics from the Grid settings.  This property is a combination of three standard properties of the grid:  FontBold, FontUnderline, and FontItalic.


Grid ColumnForeColor Property

See Also	Example	Group

Usage	grid.ColumnForeColor(column) = colorvalue

Read/Write at run time.  Not available at design time.

Split-specific property

Description	This property denotes the color of the specified column's foreground.  If this setting is left to the default of negative one (-1) then the ColumnForeColor will inherit the grid's ForeColor setting.

The grid applies color using an attribute precedence scheme.  Attribute precedence is the order in which color and font properties are applied to the grid.  The precedence for ColumnForeColor is two (2).


Grid ColumnHasRegexAttr Property

See Also	Example	Group

Usage	grid.ColumnHasRegexAttr(column) = boolean

Read/Write at run time.  Not available at design time.

Split-specific property

Description	Setting this value to False removes all the regular expressions that have been added to the specified column using ColumnAddRegexAttr.   Setting this value to True has no effect.  If ColumnHasRegexAttr has been set to False then setting ColumnAddRegexAttr resets ColumnHasRegexAttr to True.

This property returns True if ColumnAddRegexAttr has been set at leaset once.  If ColumnAddRegexAttr has never been set then it returns False.


Grid ColumnHeadFontStyle Property

See Also	Example	Group

Usage	grid.ColumnHeadFontStyle(column) = numericexpression

Read/Write at run and design time.

Split-specific property

Values	0 - Inherit

1 - Normal

2 - Bold

3 - Italic

4 - Bold + Italic

5 - Underline

6 - Underline + Bold

7 - Underline + Italic

8 - Underline + Bold + Italic

Description	This property allows you to set the Font characteristics for the specified column heading.  The default, 0 - Inherit, means that the column heading will inherit the Font characteristics from the Grid settings.  This property is a combination of three standard properties of the grid:  FontBold, FontUnderline, and FontItalic.


Grid ColumnIndex Property

See Also	Example	Group

Usage	grid.ColumnIndex = integerexpression

Read/Write at run time.  Not available at design time.

Split-specific property

Description	This property denotes the one-based index of the current cell's column position.  It may be set at run time to highlight a different cell within the current row.  If the column is visible, the marquee will be moved to the selected column.  If the column is not visible, the grid will scroll to make it visible as a result of setting this property.

Immediately after a new grid is created, there is no layout, so this property has a value of zero (0), even though technically this value is out of range.


Grid ColumnName Property

See Also	Example	Group

Usage	grid.ColumnName(column) = stringexpression

Read/Write at run time.  Access via Layout Editor at design time.

Property is global

Description	This property holds the heading text for a grid column.  It is set to the appropriate DataField name automatically when the Layout Editor property is selected and DataSource is set to a properly specified database.  It may also be set at run time in either callback or database mode.  If the string is too large and HeadingHeight is large enough the text will wrap, otherwise it will clip at the word boundary.

In callback mode, a value should be supplied if headers are desired, either via the Layout Editor or in code at run time.

The Layout Editor may be used at design time to change the default values used in automatic database mode, or to assign new values for callback mode.

When assigning a value to this property, you can use a column index one greater than the maximum number of columns currently contained in the grid (returned by the Columns property).  The grid will create a new column and automatically increase the column count.


Grid ColumnOrder Property

See Also	Example	Group

Usage	grid.ColumnOrder(index) = integerexpression

Read/Write at run time.  Access via Layout Editor at design time.

Split-specific property

Description	This property holds the one-based sequence number for a grid column (i.e., the position of the column within the grid layout).  In database mode, columns are initially ordered according to the database field layout.

At run time, this property array is changed automatically when the user shuffles columns with the mouse.  You can change this property using code, which causes the columns to appear in a different order in the grid.

When you refer to a column element in code, the order of the columns in the grid does not need to be known.  For example, referring to ColumnName(1) will always access the same column name, regardless of whether the columns have been moved by the user or whether their ColumnOrder property has been changed.  This allows code to be consistent while still permitting users to customize column positions to their liking.


Grid ColumnRectLeft Property

See Also	Example	Group

Usage	width = grid.ColumnRectLeft(column)

Read-only at run time.  Not available at design time.

Split-specific property

Description	If the current column is visible, this property returns the location of the left boundary of the current column (using the scale units of the control's container).  If the current cell is not visible, this property returns zero (0).

This property and other cell and column dimension and location properties enable you to easily implement some useful location-specific features.  Examples might be drag and drop, popping up balloon help, or other controls such as a combo box or your own edit window.


Grid ColumnRectWidth Property

See Also	Example	Group

Usage	width = grid.ColumnRectWidth(column)

Read-only at run time.  Not available at design time.

Split-specific property

Description	If the current cell is visible, this property returns the width of the current cell (using the scale units of the control's container).  If the current cell is not visible, this property returns zero (0).

This property and other cell and column dimension and location properties enable you to easily implement some useful location-specific features.  Examples might be drag and drop, popping up balloon help, or other controls such as a combo box or your own edit window.


Grid Columns Property

See Also	Example	Group

Usage	grid.Columns = integerexpression

Read/Write at run-time.  Not available at design time.

Property is global

Description	This property returns the number of columns currently defined for the grid.  This value reflects the number of columns which can potentially be displayed, but does not reflect the number of actual columns displayed.  This depends upon whether columns are visible (using the ColumnVisible property) and whether they are scrolled off the display on the right or left.

In callback and database modes, columns are created automatically when properties such as ColumnName are used to assign characteristics to a new column.

The value of Columns may be set to zero, which will physically remove all column information from the grids memory.  All data and headings will be cleared, and the ColumnIndex property will subsequently return zero (0), indicating that there is no data on the grid.


Grid ColumnSetStatusAttr Property

See Also	Example	Group

Usage	grid.ColumnSetStatusAttr(column) = numericexpression

Write only at run time. Not available at design time.

Split-specific property

Values	GFS_CURCELL = &H1	' Current cell

GFS_HIGHROW = &H2	' Highlighted row

GFS_CHANGED = &H4	' Updated cell

GFS_SELECTED = &H8	' Marked row

 0	' Cells with none of the above status types

Description	This property allows you to control the color of a cell in the specified column based on the assigned cell status.  Before this property is set to the specified cell status, the programmer must also set three additional properties:  ParamBackColor, ParamForeColor, and ParamFontStyle,

The assigned cell status determines the condition that must be satisfied before the color attributes will be applied to a given cell in the specified column - the cell status must match with the ColumnSetStatusAttr value.  If this condition is satisfied, then ParamBackColor, ParamForeColor, and ParamFontStyle will be applied when displaying the cell.

There are four (4) basic cell status (GFS_CURCELL, GFS_HIGHROW, GFS_CHANGED, GFS_SELECTED).  A cell can have any of the sixteen (16) possible combinations of the four basic status.  Simply add (or Or'ed) the values of the applicable basic status to get the cell status you want.  For instance, to indicate a cell is Selected and also Current, use a cell status value equal to GFS_CURCELL Or GFS_SELECTED, this could also be expressed as &H9.

A ColumnSetStatusAttr of zero (0) applies to all cells which do not have any of the four status bits set.

Every time this property is set, the ColumnSetStatusAtttr condition is added to the list of existing conditions.  Hence, by repeated use of this property it is possible to set up multiple conditions to affect the display appearance of the grid.

If one of the Param properties is not set before calling ColumnSetStatusAttr it will use the previous setting for that property.  If the Param property has never been set then it will inherit the existing grid property.  It is best to explicitly set all four Param properties before each call so that you dont get unexpected behavior .

The grid applies color using an attribute precedence scheme.  Attribute precedence is the order in which color and font properties are applied to the grid.  The precedence for ColumnSetStatusAttr is seven (7).

This property can only be written to and cannot be read.  If you attempt to read this property at run-time an error will occur.


Grid ColumnSize Property

See Also	Example	Group

Usage	grid.ColumnSize(column) = numericexpression

Read/Write at run time and design time.

Property is global

Description	This property holds the database width, in bytes, for each grid column.  It is set to the appropriate field width (not display width) automatically when the DataSource property is set and the LayoutEditor is chosen for the first time.  It may also be set at run time in either callback or database mode.

This property does not affect the grid layout, but imposes a limit on the number of characters that may be entered when editing a cell.  If set to zero (0), no such limits are imposed.

In database mode, if the database does not supply a width value, then no limits are imposed.  In either callback or database mode, a value may be supplied in code at run time in order to restrict the amount of data the user can enter.

When assigning a value to this property, you can use a column index one greater than the maximum number of columns currently contained in the grid (returned by the Columns property).  The grid will create a new column and automatically increase the column count.


Grid ColumnStyle Property

See Also	Example	Group

Usage	grid.ColumnStyle(column) =numericexpression

Read/Write at run time.  Access via Layout Editor at design time.

Split-specific property

Values	GRS_LEFT = 0	' Left justify column

GRS_CENTER = 1	' Center column

GRS_RIGHT = 2	' Right justify column

GRS_HSAME = &H0	' Heading same as column

GRS_HLEFT = &H10	' Left justify heading

GRS_HCENTER = &H20	' Center heading

GRS_HRIGHT = &H30	' Right justify heading

GRS_READONLY = 8192 	' Disable editing for column

Description	This property determines justification and editability for a grid column.  By default, grid columns are left-justified and editable, with the exception of numeric columns, which are right-justified and editable.  This property is set to the appropriate value when the DataSource property is set and the Layout Editor is selected for the first time.  It may also be set at run time in either callback or database mode.  The Layout Editor may be used at design time to change the default database mode values, or to assign new values for callback mode.

When setting the ColumnStyle property, use one of the first three values for column cell style, Or'ed with the next four for heading style, and optionally Or'ed with the last one to disable editing for the specified column.  When assigning a value to this property, you can use a column index one greater than the maximum number of columns currently contained in the grid (returned by the Columns property).  The grid will create a new column and automatically increase the column count.


Grid ColumnSum Property

See Also	Example	Group

Usage	total = grid.ColumnSum(column)

Read/Write at run time.  Not available at design time.

Property is global.

Description	This property returns the current cumulative total of the column specified by column.  This value is maintained by TrueGrid only if ColumnSumEnable has been set to True for the specified column.

TrueGrid does not calculate a column sum unless you request it.  Setting ColumnSumEnable to True doesn't force TrueGrid to perform summary calculations.  However, as soon as you access the ColumnSum property, TrueGrid will calculate the initial column sum automatically.  Subsequent accesses to ColumnSum will return the internally maintained value, rather than requiring recalculation of the sum.  When you perform a Refresh operation on the attached Data Control, TrueGrid makes a note of this, and will recalculate the summary the next time you reference ColumnSum.

Although TrueGrid will automatically calculate the sum when required, this can be time consuming for large databases since it requires reading each record.  If an application knows the column total in advance, your program can seed the summary value by assigning a value to this property before the first time you reference it.  Once seeded, TrueGrid will maintain the internal value for you as data is changed.

Although this property represents a numeric quantity, it actually returns a string.  This is because Visual Basic properties cannot return numeric values with greater precision than a single-precision floating point number.  Since summary data can easily exceed this precision, TrueGrid keeps the internal summary as a 20-digit BCD (binary-coded decimal) number to avoid rounding errors.  When you access this property, TrueGrid converts the BCD number to a string.  Assigning a string to this property converts it automatically to the internal BCD format used for column summary maintenance.


Grid ColumnSumEnable Property

See Also	Example	Group

Usage	grid.ColumnSumEnable(column) = boolean

Read/Write at run time.  Not available at design time.

Property is global.

Description	This property enables or disables automatic column summaries for the column specified by column.  When set to True, TrueGrid automatically maintains an internal total for numeric columns using an optimized algorithm which minimizes database access.  In effect, TrueGrid calculates the column summary once, then maintains the value as information is modified interactively or by your program code (using Visual Basic methods such as Edit and Update).

When ColumnSumEnable is set to True, TrueGrid will immediately fire the ColumnSumChange event, which notifies your program that you need to display summary information.  This event will be fired even if there is no data in the grid, assuming that you want to know even if the sum is currently zero.

Setting this property to False disables column summary calculation for the column.  You may change this property as often as you wish, depending upon your application's needs.

By default, column summaries are disabled for all columns.


Grid ColumnText Property

See Also	Example	Group

Usage	stringvar = ColumnText(column)

Read/Write at run time.  Not available at design time.

Split-specific property

Description	This property returns the cell text of the current row of the specified column.  The column number must be between 1 and the maximum number of columns (specified by Columns).

If the cell text has been edited, then the edited contents are returned rather than the actual value of the data in the database. ColumnText will not be correct while the grids EditActive property is True.  When the grid is in edit mode you should use the Text property to get the current cells contents.

The value of the ColumnText property may be set at runtime.  This has the same effect as interactive editing of the cell, but the cell never enters editing mode.  Setting ColumnText causes the value of ColumnChanged for the column to become True.

ColumnText refers to text within the row specified by the ReferenceRow property (which is usually automatically set to the value of RowIndex).  However, in the UnboundFetch, FetchAttributes, FetchMargins, and QueryMark events, TrueGrid automatically sets ReferenceRow to the row being fetched or queried rather than the row specified by RowIndex.  You cannot set ColumnText unless the ReferenceRow is the same as the RowIndex (you can only change the current row's data), but you can access ColumnText for any valid setting of ReferenceRow.

Setting ColumnText for any column within an unbound column's Update event will automatically cause the unbound column's cell color to change to the updated color (usually red).

This property is typically used in conjunction with ColumnChanged in order to perform data validation on the entire modified grid row.


Grid ColumnType Property

See Also	Example	Group

Usage	grid.ColumnType(column) = numericexpression

Read/Write at run time.  Access via Layout Editor at design time.

Property is global

Values	0 - bound

1 - unbound

2 - calculated

Description	This property defines the way each column will function in Database mode.  By default all columns are bound.  This means that each column will automatically link to a field in the Data Control using the ColumnField property.

If the ColumnType is set to 1- unbound, then the column will not be bound to the database but instead will depend upon the UnboundFetch event for the values it needs to display.

If the ColumnType is set to 2 - calculated, then the grid will evaluate the Visual Basic expression defined in the ColumnExpression property and display the result.

The Layout Editor may be used at design time to change the default value of this property for each individual column.  In the Column Properties editor you can select one of the above three styles.

In database mode all three settings are valid.  In callback mode unbound and calculated modes are valid but bound is not.  Also in callback mode any unbound columns call the Fetch event instead the UnboundFetch event.


Grid ColumnVertScroll Property

See Also	Example	Group

Usage	grid.ColumnVertScroll(column) = numericexpression

Read/Write at run time.  Not available at design time.

Split-specific property

Values	0 - None

1 - Always

2 - Automatic

Description	This property determines the status of the scrollbar in a dropdown text box.  By default this property is set to 2 - Automatic.  In this mode the grid displays the scrollbar based on whether there is enough room below the selected cell to display all the information in the dropdown text box.  If for example, the selected cell is the next to the last row and there are three rows of information the scrollbar will appear.  If that same row is nearer the top then the scrollbar would not appear.

If this property is set to 1 - Always then the scrollbar will always appear regardless of whether or not there is enough room within the current column to display all the text.

When set to 0 - None the scrollbar is never displayed.  It is important to note that if you have this setting and there are more columns then the grid can display the user can access these additional columns only by the navigating the cells via the tab or arrow keys.


Grid ColumnVisible Property

See Also	Example	Group

Usage	grid.ColumnVisible(column) = boolean

Read/Write at run time and design time.

Split-specific property

Description	This property determines whether a given column is actually displayed.  At run time, when the user resizes a column down to nothing, this property is set to False for the corresponding column, but the prior width is retained.  There is no way for the user to get the column back unless the application developer provides a menu item or button that resets this property to True.

When assigning a value to this property, you can use a column index one greater than the maximum number of columns currently contained in the grid (returned by the Columns property).  The grid will create a new column and automatically increase the column count.

The grid will be automatically refreshed to show or hide the chosen column.


Grid ColumnWidth Property

See Also	Example	Group

Usage	grid.ColumnWidth(column) = integerexpression

Read/Write at run time.  Access via Layout Editor at design time.

Split-specific property

Description	This property holds the display width, in character units, for each grid column.  It is set to the appropriate value automatically when the DataSource property is set and the Layout Editor property is selected for the first time.  It may also be set at run time in either callback or database mode.

The actual column width depends upon the current font.  For fixed-width fonts, columns will be the exact widths as ColumnWidth specifies.  For proportional fonts, the unit of measurement is the average character width for the current font.

When assigning a value to this property, you can use a column index one greater than the maximum number of columns currently contained in the grid (returned by the Columns property).  The grid will create a new column and automatically increase the column count.  When this property is changed, the grid will automatically reflect the changes and refresh.


Grid ColumnWordWrap Property

See Also	Group

Usage	grid.ColumnWordWrap(column) = boolean

Read/Write at design time and run time.

Split specific property

Description	Setting this property affects whether or not the specified column wraps the last word on the line for that column or truncates the last word at the column border.  This property can be set for each column at design time by checking the WordWrap check box in the Column Properties Dialog.  It can also be set in code at run time.

By default this property is set to True.  Commonly you will set this property to False if you have LinesPerRow set to one and you want to display a part of the last word even if its truncated.


Grid Configurable Property

See Also	Example	Group

Usage	grid.Configurable = boolean

Read/Write at design time and run time.

Split-specific property

Description	This property determines whether the user can move and resize grid columns at run time.  By default, both of these operations are permitted.  If this property is changed while the user is resizing or adjusting columns, then it will not take effect until the user has completed the current operation.


Grid CurCellVisible Property

See Also	Example	Group

Usage	grid.CurCellVisible = boolean

Read/Write at run time.  Not available at design time.

Split-specific property

Description	This property returns True if the current cell (indicated by RowIndex and ColumnIndex) is visible within the displayed area of the current split.  It returns False if the cell is not visible.  Setting this property to True will scroll the grid so that the current cell is in view.  Setting it to False is meaningless and is ignored.


Grid DataChanged Property

See Also	Example	Group

Usage	grid.DataChanged = boolean

Read/Write at run time.  Not available at design time.

Property is global

Description	When a Data Control moves from record to record, the grid automatically moves its highlighting to the new row and DataChanged is set to False.  If the data in the grid has been changed in any way other than moving to a different record, DataChanged becomes True.

Any grid data which has been changed is highlighted in red (by default) to indicate that it hasn't been written to the database.  If DataChanged is True, you can inspect the values of ColumnChanged and ColumnText to determine the exact nature of the changes.

When the Data Control starts to move to a different record, the Validate event occurs.  Then if DataChanged is True for the grid, the Data Control invokes the Edit and UpdateRecord methods.  Finally, data from the grid is saved to the database.

In the code for the Validate event, you can set this property to False when you do not want to save the data in the database.  When set to False, any update highlighting which indicated that the user has changed data disappears and the original data will appear in its place.


Grid DataMode Property

See Also	Group

Usage	grid.DataMode

Read only at run time.  Read/Write at design time.

Property is global

Values	0 - Database Mode (default)
1 - Application Mode

Description	This property determines whether the grid fetches cell data from a database or from the application (via the Fetch event).

The phrase "database mode" means that DataMode is 0.  The phrase "callback mode" means that DataMode is 1.

When this property is set to 1, the grid operates in callback mode, in which it sends the Fetch event to obtain cell data.  This allows the grid to be used to browse and edit Visual Basic arrays, DOS files, or other application-defined data.

When the property value is zero, the grid manages all database operations completely.  In such cases, the database in use is determined by the setting of DataSource property.  In database mode, the Fetch event is never sent.

This property cannot be changed at runtime, so grids must operate in one mode or the other at all times.


Grid DataSource Property

See Also	Group

Usage	Read/Write at design time.  Not available at run time.

Property is global

Description	This property is used to bind the TrueGrid control to a Data Control.  It must be set at design time, and cannot be changed while the program is running.  In order to set DataSource, a Data Control must already be present on the same form as the grid control.  If this property is not set at design time then the DataSourceHwnd can be used to dynamically bind the grid across forms.

Once the DataSource property is set, clicking on the Layout property will ask whether the database layout should automatically be used by the grid.


Grid DataSourceHwnd Property

See Also	Example	Group

Usage	grid.DataSourceHwnd = integer

Read/Write at run time. Not available at design time.

Property is global

Description	When you set the DataSource property of a grid to a Data Control, the Data Control must be in the same form as the grid.  This property is used to bind a grid to a Data Control which is on a different form.  Instead of assigning the DataSource property to a Data Control at design time, at run time, the programmer assigns the Hwnd of a Data Control to the DataSourceHwnd property  The Hwnd of a data control can be obtained by calling the TgGetControlHwnd function which is provided by TrueGrid.  The function declaration for TgGetControlHwnd is in TGCONST.TXT.  Make sure you copy the declaration or include TGCONST.TXT in your project.

If a grid is bound to a Data Control on a different form, do not unload the form that contains the Data Control if the form containing the grid is still loaded.  As a precaution, you should disable the user's ability to unload the form where the Data Control resides.  The easiest way to do this is by setting the Visual Basic Control Box property to False.


Grid Editable Property

See Also	Example	Group

Usage	grid.Editable = boolean

Read/Write at design time and run time.

Property is global

Description	This property determines whether the contents of the grid can be edited directly.  By default, they can.

If this property is True, it may be overridden by the ColumnStyle property for an individual column if the GRS_READONLY flag is in effect.  However, if this property is False, then no editing events will be accepted for any column, regardless of ColumnStyle.

If the user is editing the current cell when this property is changed, the edit will continue as usual.  However, no further editing will be permitted after the current edit is complete.

If the Data Control associated with the grid has its ReadOnly property set to True, then editing will not be permitted, even if this property is set to True.  However, the value of the Editable property itself will not be affected.

Use a one-column grid in callback mode with the Editable property set to True to provide a list box in which the user can edit items directly.


Grid EditActive Property

See Also	Example	Group

Usage	grid.EditActive = boolean

Read/Write at run time.  Not available at design time.

Split-specific property

Description 	If this property returns True, then the current cell is currently being edited by the user.  If False, then no editing is in progress.  Setting this property to True will cause editing to begin on the current cell (if it is not already in edit mode).  Setting it to False will exit edit mode.  If the cell has been modified, this causes the Validate and Update events to be sent.  If you want to cancel editing, set the Modified property to False and then set EditActive to False.


Grid EditBackColor Property

See Also	Example	Group

Usage	grid.EditBackColor = colorvalue

Read/Write at design time and run time.
Split-specific property

Description	This property denotes the background color of the grid's editing window when editing is in progress.  This property defaults to the system highlight color (0x800000D).  If editing is in progress, the color of the edit area will not be changed until the current edit has been completed.

You can set this color by clicking on the ellipsis in the properties window .  A color palette will appear which allows you to select a color.  You can also type the hexadecimal value of a color directly into the settings box.


Grid EditDropDown Property

See Also	Example	Group

Usage	grid.EditDropDown = boolean

Read/Write at design time and run time.

Property is global

Description	This property is set to True by default.  When True an edit window will pop up when editing a cell whose contents cannot all be displayed within the confines of the cell's current boundaries.  This drop down will only extend to the bottom of the grid.  If this property is set to False editing will be confined to the cell's rectangle.

When the drop down box is enabled editing within the cell is just like editing in a standard multiple line VB text box.  The Sel properties can still be used and navigation through the cell is exactly the same as a standard text control.  The limit for editing is 64k or available memory.  If the user tries to edit the last row in the grid the EditDropDown will not occur and the user will have to edit within the current cell's boundaries.


Grid EditForeColor Property

See Also	Example	Group

Usage	grid.EditForeColor = colorvalue

Read/Write at design time and run time.
Split-specific property

Description	This property denotes the color of the grid's editing window text when editing is in progress.  By default this property is the System Highlight Text Color (0x8000000E).  If editing is in progress, the color of the edit area will not be changed until the current edit has been completed.

You can set this color by clicking on the ellipsis in the properties window.  A color palette will appear which allows you to select a color.  You can also type the hexadecimal value of a color directly into the settings box.


Grid EditMask Property

See Also	Example	Group

Usage	grid.EditMask(column) = stringexpression

Read/Write at run time.  Access via Layout Editor at design time.

Property is global

Description	The EditMask property allows you to specify a Visual Basic Format String which will be used for formatting all data displayed in the specified column.  At design time, you can use the Layout Editor to set a pre-defined value for this edit mask.

The format string will be used only for displaying data.  Data input will occur in unformatted mode and the data will be reformatted when editing is complete.  If you do not include an edit mask, or you set the EditMask property to an empty string, then data will be displayed in the standard Visual Basic string representation for the field.


Grid ExposeCellMode Property

See Also	Example	Group

Usage	grid.ExposeCellMode = numericexpression

Read/Write at design time and run time.

Property is global

Values	0 - Expose upon select
1 - Expose upon edit
2 - Leave cell clipped

Description	This property controls how the rightmost column reacts when clicked by the user.  When set to 0 (the default) the grid will scroll to the left to make the cell visible so all of its text can be shown.  This can be somewhat disconcerting to the user if they commonly click on grid to begin editing (the grid will always shift to the left when the user clicks).

If set to 1 then the grid will not move when clicked initially, however if the user attempts to edit the cell then the grid will scroll left so you can see all of the cell text.  This is exactly how Excel works and is probably the most intuitive.

If ExposeCellMode is set to 2 then the grid will always leave the last cell clipped both when clicked and when the user attempts to edit the cell.  Note however that editing may be tough if there isn't much of the column visible.  The chief reason to implement this is if you know there will always be enough space available for editing (or if you disallow editing) and you never want the grid to shift accidentally.


Grid ExtendRightCol
Grid ExtendRightCol Property

See Also	Example	Group

Usage	grid.ExtendRightCol = boolean

Read/Write at run time.  Not available at design time.

Split-specific propety

Description	ExtendRightCol property allows the right column to extend to the end of the grid or current split if it can accommodate all of the visible columns.  The default is True meaning that the last column will extend to the end of the grid.  If False the area between the last column and the end of the grid will be grayed out.  If the grid or split cannot accomodate all of the visible columns (usually when the horizontal scrollbar is visible) then this property will be ignored.


Grid FetchMode Property

See Also	Example	Group

Usage	grid.FetchMode = numericexpression

Read/Write at design time and run time.

Property is global

Values	0 - By cell (default)
1 - By row
2 - Entire grid

Description	This property determines how the grid fetches data when it needs to be displayed.  By default, TrueGrid displays one cell at a time.  Normally, this is so fast that there is no perceived delay at all.  However, some database formats may fetch cell data slowly (e.g. large servers, data access using ODBC), so that the user perceives an undesirable delay.  Changing this property may increase the perceived smoothness of the display, although it will not affect the actual time necessary to complete displaying the data.

The property has the following possible values:

0 - By cell

The grid will refresh each cell individually.  In database mode, each cell will be fetched separately and displayed separately.  This is the default setting and normally doesnt need to be changed.  Database fetches are frequently so fast that the user cannot perceive the cell-by-cell display.  In callback mode, the Fetch event will be sent immediately before each cell is displayed.

1 - By row

The grid will fetch each cell in a row, then display the entire row.  If using a slow database engine (such as a remote SQL server), or using callback mode with a slow Fetch event, this setting may be perceived better by the user, since each row will appear quickly (but there will still be a delay between displaying rows).  With this setting, TrueGrid will display an hourglass cursor if the fetch operations are sufficiently slow that the user can perceive the delay.

2 - Entire grid

This setting causes the grid to fetch all data in the entire grid display, then display it all at once.  TrueGrid will display an hourglass cursor if the fetch operations are sufficiently slow that the user can perceive the delay.

Note that the setting of this property has no effect on the operation of TrueGrid, nor the actual performance of the fetch event.  It only affects the method used for the display.


Grid HasRegexAttr Property

See Also	Example	Group

Usage	grid.HasRegexAttr = boolean

Read/Write only at run time. Not available at design time.

Split-specific property

Description	Setting this value to False removes all the regular expressions that have been added using AddRegexAttr.   Setting this value to True has no effect.  If HasRegexAttr has been set to False then setting AddRegexAttr resets HasRegexAttr to True.

This property returns True if AddRegexAttr has been set at leaset once.  If AddRegexAttr has never been set then it returns False.


Grid HeadBackColor Property

See Also	Example	Group

Usage	grid.HeadBackColor = colorvalue

Read/Write at design time and run time.

Split-specific property

Description	This property denotes the background color of the grid's headings.  This property defaults to the System Active Caption Color (0x80000002).  This color will be displayed only while the grid has focus.  When the grid loses focus, the heading colors are determined by the current setting of InactiveForeColor and InactiveBackColor.

You can set this color by clicking on the ellipsis in the properties window.  A color palette will appear which allows you to select a color.  You can also type the hexadecimal value of a color directly into the settings box.


Grid HeadForeColor Property

See Also	Example	Group

Usage	grid.HeadForeColor = colorvalue

Read/Write at design time and run time.

Split-specific property

Description	This property denotes the color of the grid's heading text.

This color will be displayed only while the grid has focus.  This property default to the System Caption Text Color (0x80000009).  When the grid loses focus, the heading colors are determined by the current setting of InactiveForeColor and InactiveBackColor.

You can set this color by clicking on the ellipsis in the properties window.  A color palette will appear which allows you to select a color.  You can also type the hexadecimal value of a color directly into the settings box.


Grid HeadFontStyle Property

See Also	Example	Group

Usage	grid.HeadFontStyle = numericexpression

Read\Write at run and design time.

Split-specific property

Values	0 - Inherit (default)

1 - Normal

2 - Bold

3 - Italic

4 - Bold + Italic

5 - Underline

6 - Underline + Bold

7 - Underline + Italic

8 - Underline + Bold + Italic

Description	This property allows you to set the Font characteristics for the grid's heading.  The default setting of zero (0) means that the column will inherit the Font characteristics from the Grid settings.  This property is a combination of three standard properties of the grid:  FontBold, FontUnderline, and FontItalic.


Grid HeadingHeight Property

See Also	Example	Group

Usage	grid.HeadingHeight = floatingpointvalue

Read/Write at run time and design time.

Property is global

Description	This value indicates the height of the heading, in rows.  If you want to change the height of the headings to be larger than the standard row you would use a value larger than one.  If you wanted smaller headings then use a value less than one.  A value of 1.5 would mean the grid's heading height would be equal to the height of one and one half rows.


Grid Headings Property

See Also	Example	Group

Usage	grid.Headings = boolean

Read/Write at design time and run time.

Split-specific property

Description	This property determines whether the grid displays column headings.  Setting this property to False allows an additional row of data to be displayed.

The grid will be redrawn in its entirety to effect the change.  Setting this property to False disables column movement by the user, since you can only move a column at run time by grabbing its header.  Column resizing is not affected. Setting this property to False will also erase the vertical scroll bar if all records become visible.

You can control the headings on a per-split basis.  However, all splits which are part of the same split group (see SplitGroup) will reserve room for their headings so long as at least one of the splits in the group has Headings set to True.  If all splits which are members of the group have Headings set to False, then no headings will appear and no space will be reserved for them.


Grid HorzColor Property

See Also	Example	Group

Usage	grid.HorzColor = colorvalue

Read/Write at design time and run time.

Split-specific property

Description	This property denotes the color of the grid's horizontal lines.  This property defaults to the System Window Frame Color (0x80000006).  This color is only meaningful if horizontal lines are turned on, via the HorzLines property.

You can set this color by clicking on the ellipsis in the properties window.  A color palette will appear which allows you to select a color.  You can also type the hexadecimal value of a color directly into the settings box.


Grid HorzLines Property

See Also	Example	Group

Usage	grid.HorzLines = numericexpression

Read/Write at design time and run time.

Property is global

Values	0 - None (default)
1 - Single
2 - 3D

Description	This property determines whether the grid displays horizontal lines between rows.

If the value of this property is 0 - None, then no lines are displayed.  If the value is 1 - Single, then single-width lines are displayed in the color specified by HorzColor.

If the value of this property is 2 - 3D, then the grid will attempt to draw the lines in 3D mode.  The grid uses the HorzColor value for the darker border of the 3D "groove" between cells, and chooses another color from the available colors in the system palette.  Some experimentation is usually required to achieve the desired effect.  The standard grey 3D effect is chosen by selecting a dark grey color for the lines and a medium grey for the grid background color.

The grid will be redrawn in its entirety to effect the change.  Changing this property to a non-zero value may decrease the number of lines which may be displayed (since horizontal lines take up a bit more space).


Grid HorzScrollbar Property

See Also	Example	Group

Usage	grid.HorzScrollbar = numericexpression

Read/Write at design time and run time.

Split-specific property

Values	0 - None

1 - Always

2 - Automatic

Description	This property determines the status of the Horizontal Scrollbar.  By default this property is set to 2 - Automatic.  In this mode the grid displays the scrollbar based on whether there is enough room to display all the columns.  If the sum of the display width exceeds the width of the grid then the scroll bar will appear otherwise it will not.

If this property is set to 1 - Always then the horzontal scrollbar will always appear regardless of whether or not all the columns fit into the grid display area.

When set to 0 - None the Horizontal scrollbar is never displayed.  It is important to note that if you have this setting and there are more columns then the grid can display the user can access these additional columns only by the navigating the cells via the tab or arrow keys.

This property operates slightly different when there is more than one split on the grid.  If you set one of the split's HorzScroll bar to none, it will remove the scrollbar arrow buttons and the scroll button and replace it with a blank area.  This is to keep continunity across the the multiple splits.  To completely remove the Horzontal scroll area you need to turn off the scroll bar for all the splits.  To set the horizontal scroll bar for a SplitGroup just set the horizontal scroll bar for one split in the group.

Setting this property at run time causes a momentary flicker while the grid is repainting it's scrollbars.


Grid HwndEdit Property

Group

Usage	integer = grid.HwndEdit

Read only at run time.  Not available at design time.

Property is global

Description	This property operates similarly to the standard Hwnd property except that it returns the value for the Grid's edit window.  This property will return a value while the grid is being edited.  When the grid is not being edited this value is 0.

HwndEdit is available in EnterEdit, Change, Validate, and possibly MouseMove, MouseDown, MouseUp, KeyPress, KeyUp, KeyDown.  It will always be zero in RequestEdit and ExitEdit.


Grid InactiveBackColor Property

See Also	Example	Group

Usage	grid.InactiveBackColor = colorvalue

Read/Write at design time and run time.

Split-specific property

Description	This property denotes the background color of the grid's heading whenever it does not have focus. This property defaults to the System Inactive Caption Color (0x80000003).

When the grid does have focus, the heading color is controlled by either the default system settings or HeadForeColor and HeadBackColor properties.

You can set this color by clicking on the ellipsis in the properties window.  A color palette will appear which allows you to select a color.  You can also type the hexadecimal value of a color directly into the settings box.

The grid headings will automatically be redrawn in the new color if the grid currently does not have focus.


Grid InactiveForeColor Property

See Also	Example	Group

Usage	grid.InactiveForeColor = colorvalue

Read/Write at design time and run time.

Split-specific property.

Description	This property denotes the color of the grid's heading text whenever the grid does not have focus. This property defaults to the System Inactive Caption Text Color (0x80000013).

When the grid does have focus, the heading color is controlled by either the default system settings or the HeadForeColor and HeadBackColor properties.

You can set this color by clicking on the ellipsis in the properties window.  A color palette will appear which allows you to select a color.  You can also type the hexadecimal value of a color directly into the settings box.

The grid headings will automatically be redrawn in the new color if the grid currently does not have focus.


Grid InsertSplit Property

See Also	Example	Group

Usage	grid.InsertSplit = integerexpression

Write only at run time.  Not available at design time.

Property is global

Description	This property allows you to insert a split at a given position.  Setting this property places a new split to the left of the split referenced.  The new split inherits all of the properties of the split to the right.  All splits to be right of the new split will have their split indexes shifted up by one.

If this property is set to one greater than the number of splits that currently exists then a new split will be created to the right of the last split.


Grid Layout Property

See Also	Example	Group

Usage	grid.Layout = stringexpression

Read/Write at design and run time.

Property is global

Description	At design time, clicking on this property brings up the Layout Editor, which allows customization of column settings and other grid configuration options.

Within the properties window, one of the following non-editable strings is displayed:

(none)	No layout information exists.

(database)	Default layout information was read from the DataSource property.

(modified-database)	The user made changes to a database layout using the Layout Editor.

(user-defined)	Layout created from scratch.

If the layout is set to (none) then the grid will configure itself automatically at run time after the Form_Load event.  If you want to set additional properties on the grid in Form_Load refresh the data control and execute a DoEvents function.  This will force the grid to configure and then allow you to set your additional settings.  If the layout is set to any of the other three settings it will not configure at run time and hence setting grid properties in Form_Load should not be a problem.

At run time, the Layout property contains a string which defines all properties of the grid that can set in the Layout Editor, including splits, columns, and column settings, etc.  You can save the contents of the Layout property in a string and restore it later by reassigning it to the Layout property.  This is useful if you are switching between several different databases or SQL statements and still allowing the user to configure the grid.

The format of the string is internal, and is checked for validity upon assignment.  The string may contain null characters, so special care should be taken when storing it in a file or INI file.  You need to store it in either a binary file or a binary field in a database.


Grid LayoutIndex Property

See Also	Group

Usage	grid.LayoutIndex = numericexpression

Read/Write at design time and run time.

Property is global

Description	Use this property to configure multiple layouts at either design time or run time.  By changing the LayoutIndex value you can set up several layouts and switch between them at run time.

To use a design time simply layout the first grid using the Layout Editor.  When you are done with the first layout simply change the LayoutIndex property.  You will notice that the grid does not automatically clear the previous layout.  This is done assuming that in most cases you are going to want to only modify the existing layout.  If you need to clear the layout simple go into the Layout Editor and chose clear fields from the Control Box menu.

At run time you can save or switch to different layout.  If the user modifies the grid and you want to save the layout simply switch to a new index number.  Now any changes made to the grid will be saved to the new layoutindex value and you can revert to the old layout at anytime.:


Grid LeftColumn Property

See Also	Example	Group

Usage	grid.LeftColumn = numericexpression

Read/Write at run time.  Not available at design time.

Split-specific property.

Description	This property denotes the one-based index of the leftmost grid column.  You can use this property to scroll the grid horizontally in code at run time.  Note however that this will only work if the user has not changed the sequential order of the columns.  If the user scrolls the grid using the horizontal scroll bar, this property will contain the column number of the column which is currently at the left hand side of the grid.


Grid LinesPerRow Property

See Also	Example	Group

Usage	grid.LinesPerRow = integerexpression

Read/Write at design time and run time.

Property is global.

Description	This property is used to determine the number of lines a given row displays.  This property allows you to obtain a multi-line row display.  For example if you set this value to two (2) then the grid will display two lines of text for each row.  Text displayed in the cell will be word wrapped to fill the available rows in the cell.  This property is not available on a per-row bases and can only be set for the entire grid.

This property is most commonly used when the data being display is typically too long to be shown in a single-line cell.  Setting Modified does not revert the cell to its original contents, but leaves the cell text intact.  The grid simply won't recognize it as modified text and won't write it to the database if the user leaves the cell or presses Enter.


Grid MarqueeStyle Property

See Also	Example	Group

Usage	grid.MarqueeStyle = numericexpression

Read/Write at design time and run time.

Split-specific property.

Values	0 - Dotted Cell Border (Default)
1 - Solid Cell Border
2 - Highlight Cell
3 - Highlight Row
4 - Highlight Row & Cell
5 - None

Description	This property allows you to specify the method which the grid will use to highlight the current row and cell in the grid.  There are six possible values for this property:

0 - Dotted Cell Border
The current cell within the current row will be highlighted by drawing a dotted border around the cell.  In Microsoft Windows terminology, this is usually called a focus rectangle.  This is the default value for this property.

1 - Solid Cell Border
The current cell within the current row will be highlighted by drawing a solid box around the current cell.  This is more visible than the dotted cell border, especially when 3D line properties are used for the grid.

2 - Highlight Cell
The entire current cell will be highlighted by inverting the colors within the cell.  This provides a very distinctive block-style highlight for the current cell.

3 - Highlight Entire Row
The entire row containing the current cell will be highlighted by inverting the colors within the row.  In this mode, it is not possible to visually determine which cell is the current cell, only the current row.  When the grid is not editable, this setting is often preferred, since cell position is then irrelevant.

4 - Highlight Row and Cell
The entire row will be highlighted.  The current cell within the row will be "raised" so that it appears distinctive.  This setting doesn't appear clearly with all background and color settings.  The best effect is achieved by using 3D lines and a grey background.

5 - None
The marquee will not be shown.


Grid MarqueeUnique Property

See Also	Example	Group

Usage	grid.MarqueeUnique = boolean

Read/Write at design and run time.

Property is global

Description	This property controls the display of the Marquee when there is more than one split.  By default this property is True which means that the current cell marquee, which is displayed when MarqueeStyle is zero (0), one (1), two (2), or four (4), is only displayed in the current split.  When this property is set to False, all splits that has a visible MarqueeStyle settting will display a marquee.at the current cell.

In most cases you will only want one current cell marquee displayed in which case you can leave this property set to True.  Also note that all cell attribute properties will only recognize that one current cell when setting color and font styles when this property is set to True.

If this property is set to False you may then see several different current cell marquees.  The actual current cell is determined by the current split, but cell attribute properties will recognize the "current cell" in each split and set color and font styles accordingly.


Grid Modified Property

See Also	Example	Group

Usage	grid.Modified = boolean

Read/Write at run time.  Not available at design time.

Property is global.

Description	This property is valid only while editing is occuring within the grid.  You can check this value to see if the user has changed the existing data.  When the user changes the data then this property is set to True, otherwise it will be False.

You can also use this property to nullify the changes the user has made to the current text.  A good example would be if you wanted another key besides the Escape key to discard the users changes.  In the KeyPress event you would trap the key and set the Modified property to False.  This would revert the cell to it's original contents.


Grid ParamBackColor Property

See Also	Example	Group

Usage	grid.ParamBackColor = colorvalue

Read/Write at run time.  Not available at design time.

Property is global.

Description	This property is used as a parameter when defining the BackColor of a per-cell attribute property.  Setting this property individually has no immediate effect on the grid.  When one of the following properties is set they will use ParamBackColor to determine the BackColor: ColumnSetStatusAttr, ColumnAddRegexAttr, SetStatusAttr, or AddRegexAttr.

Setting ParamBackColor to INHERIT_COLOR (-1) means the ColumnSetStatusAttr, ColumnAddRegexAttr, SetStatusAttr, and AddRegexAttr properties have no effect no the back color of the cells.

Note that this property is not reset when any of the above properties are used, and therefore if another per-cell attribute property is set it will use the previous ParamBackColor.  This property is initialized to the constant INHERIT_COLOR.


Grid ParamFontStyle Property

See Also	Example	Group

Usage	grid.ParamFontStyle = numericvalue

Read/Write at run time.  Not available at design time.

Property is global.

Values	INHERIT_FONT

 1 - Normal

 2 - Bold

 3 - Italic

 4 - Bold + Italic

 5 - Underline

 6 - Underline + Bold

 7 - Underline + Italic

 8 - Underline + Bold + Italic

Description	This property is used as a parameter when defining the FontStyle of a per-cell attribute property.  Setting this property individually has no immediate effect on the grid.  When one of the following properties is set they will use ParamFontStyle to determine the FontStyle: ColumnSetStatusAttr, ColumnAddRegexAttr, SetStatusAttr, or AddRegexAttr.

Setting ParamFontStyle to INHERIT_FONT (0) means the ColumnSetStatusAttr, ColumnAddRegexAttr, SetStatusAttr, and AddRegexAttr properties have no effect no the font style of the cells.

Note that this property is not reset when any of the above properties are used, and therefore if another per-cell attribute property is set it will use the previous ParamFontStyle.  This property is initialized to the constant INHERIT_FONT.


Grid ParamForeColor Property

See Also	Example	Group

Usage	grid.ParamForeColor = colorvalue

Read/Write at run time.  Not available at design time.

Property is global.

Description	This property is used as a parameter when defining the ForeColor of a per-cell attribute property.  Setting this property individually has no immediate effect on the grid.  When one of the following properties is set they will use ParamForeColor to determine the ForeColor: ColumnSetStatusAttr, ColumnAddRegexAttr, SetStatusAttr, or AddRegexAttr.

Setting ParamForeColor to INHERIT_COLOR (-1) means the ColumnSetStatusAttr, ColumnAddRegexAttr, SetStatusAttr, and AddRegexAttr properties have no effect no the fore color of the cells.

Note that this property is not reset when any of the above properties are used, and therefore if another per-cell attribute property is set it will use the previous ParamForeColor.  This property is initialized to the constant INHERIT_COLOR.


Grid ParamStatus Property

See Also	Example	Group

Usage	grid.ColumnSetStatusAttr(column) = numericexpression

Write only at run time. Not available at design time.

Property is global.

Values	GFS_CURCELL = &H1	'Current cell

GFS_HIGHROW = &H2	'Highlighted row

GFS_CHANGED = &H4	'Updated cell

GFS_SELECTED = &H8	'Marked row

 0 - Cells with none of the above status types

-1 - All cells

Description	This property is used as a parameter to specify the cell status of cells when setting the ColumnAddRegexAttr, or AddRegexAttr property.  Setting this property individually has no immediate effect on the grid.

There are four (4) basic cell status (GFS_CURCELL, GFS_HIGHROW, GFS_CHANGED, GFS_SELECTED).  A cell can have any of the sixteen (16) possible combinations of the four basic status.  Simply add (or Or'ed) the values of the applicable basic status to get the cell status you want.  For instance, to indicate a cell is Selected and also Current, use a cell status value equal to GFS_CURCELL Or GFS_SELECTED, this could also be expressed as &H9.

A ParamStatus of zero (0) applies to all cells which does not have any of the four basic status.  ParamStatus defaults to negative one (-1) which applies to all cells regardless of cell status.


Grid PointX Property

See Also	Example	Group

Usage	grid.PointX = twips

Read/Write at run time.  Not available at design time.

Property is global.

Description	Specifies the X coordinate (always in twips) of the point used by ColumnAtPoint, RowAtPoint, or SplitAtPoint.  This property defaults to zero (0).  This property must be set by the programmer before asking for the Column, Row, or Split at which the point is located.


Grid PointY Property

See Also	Example	Group

Usage	grid.PointY = twips

Read/Write at run time.  Not available at design time.

Property is global.

Description	Specifies the Y coordinate (always in twips) of the point used by ColumnAtPoint, RowAtPoint, or SplitAtPoint.  This property defaults to zero (0).  This property must be set by the programmer before asking for the Column, Row, or Split at which the point is located.


Grid ReferenceRow Property

See Also	Example	Group

Usage	rownum = grid.ReferenceRow

Read/Write at run time.  Not available at design time.
Property is global

Description	This property specifies the row number which is used for references to ColumnText, CellRectLeft, CellRectTop, CellRectWidth, and CellRectHeight.  This property is useful when the cell text or coordinates need to be accessed without changing the current row number.

Although you may change the value of ReferenceRow in order to access alternate cell values, TrueGrid will internally reset ReferenceRow automatically just before the RowChange event is triggered, or when cell text is updated by the user interactively.  This assures that references to ColumnText (for example) remain consistent with expected behavior when row numbers change or whenever updates occur.

ReferenceRow also assumes a temporary value under the following circumstances:

1.	Whenever UnboundFetch, FetchAttributes, FetchMargins or QueryMark are executed.

2.	During the evaluation of a calculated expression.

3.	When data is updated in the current row, a new row has been selected, and the Data Control Validate handler is executing.

Under these circumstances, the ReferenceRow value will reflect either the row being fetched (in one of the fetch events) or the row being updated (in the case of the Data Control Validate event).  The row reflected by RowIndex may be different from ReferenceRow in such cases.

When TrueGrid assigns a temporary value to ReferenceRow, as above, it will automatically restore the old ReferenceRow value after the event in question terminates.  You may change ReferenceRow to another value in such cases, but the change will not be permanent.


Grid RefreshColumn Property

See Also	Example	Group

Usage	grid.RefreshColumn = integerexpression

Write only at run time.  Not available at design time.

Property is global.

Description	This property allows a column of data to be refreshed, if it is visible, without repainting the entire window.  If set to zero (0), the current column (ColumnIndex) is refreshed.  Otherwise, the specified column is refreshed.  If text editing is in progress, this call will have no effect on the text being edited, but will refresh the data in the other rows.  You can use the Text property to change the data in the cell being edited.

Typically, this used in callback mode, where the grid is unaware of changes made to the cell data.  In database mode, the column will be refreshed as well, but usually it is not necessary to do so.  However, if the grids Active property is set to False, the refreshed column will be filled with data from the current column of the database, although the other columns may not reflect the change.  However in database mode, RefreshColumn is useful if you change a characteristic of a column and need to have FetchMargins, UnboundFetch, or FetchAttributes called as a result.


Grid RefreshRow Property

See Also	Example	Group

Usage	grid.RefreshRow = numericexpression

Write only at run time.  Not available at design time.

Property is global.

Description	This property allows a row of data to be refreshed, if it is visible, without repainting the entire window.  If set to zero, the current row (RowIndex) is refreshed.  Otherwise, the specified row is refreshed.  If text editing is in progress, this call will have no effect on the text being edited, but will refresh the data in the other columns.  You can use the Text property to change the data in the cell being edited.

Typically, this is used in callback mode, where the grid is unaware of changes made to the cell data.  n database mode, RefreshRow is useful if you change a characteristic of a column and need to have FetchMargins, UnboundFetch, or FetchAttributes called as a result.  If the grids Active property is set to False, the refreshed row will be filled with data from the current row of the database, although the other rows may not reflect the change.

To TrueGrid, the term row number refers to the row within the overall set of data being browsed, rather than the screen row number.  Whether in callback or database mode, row 1 does not refer to the topmost row of the displayed grid, but refers to the first row of data.  A grid may contain thousands or even millions of rows.


Grid RemoveSplit Property

See Also	Example	Group

Usage	grid.RemoveSplit = integerexpression

Write only at run time.  Not available at design time.

Property is global

Description	Setting this property at run time allows you to remove any existing split.  When this property is set it removes the split indicated.  If this property is set to zero (0) then the current split will be deleted.

Once the current split is deleted all splits to the right are renumbered (their split indexes will be shifted down by 1).  You cannot set this property if there is only one split.


Grid RightColumn Property

See Also	Example	Group

Usage	longvar = grid.RowAtPoint

Read-only at run time.  Not available at design time.

Split-specific property.

Description	This property can be used to retrieve the one-based index of the rightmost grid column.  You can use this property to scroll the grid horizontally in code at run time.  Note however that this will only work if the user has not changed the sequential order of the columns.  If the user scrolls the grid using the horizontal scroll bar, this property will contain the column number of the column which is currently at the right hand side of the grid.


Grid RowAtPoint Property

See Also	Example	Group

Usage	integerexpresssion = grid.RowAtPoint

Read-only at run time.  Not available at design time.

Property is global.

Description	Returns the row which is beneath the point specified by PointX and PointY.  If the point is positioned within the header area then RowAtPoint will return zero (0).  If the the point does not lie on a grid row (e.g., outside the grid, on the grid scroll bars, etc.) then this property will return negative one (-1)

This property and other cell and column dimension and location properties enable you to easily implement some useful location-specific features.  Examples might be drag and drop, popping up balloon help, or other controls such as a combo box or your own edit window.


Grid RowIndex Property

See Also	Example	Group

Usage	grid.RowIndex = numericexpression

Read/Write at run time.  Not available at design time.

Property is global.

Description	This property denotes the one-based index of the current row position.  It may be set at run time to highlight a different cell within the current column.  When set in this fashion, the specified row will be made visible if it is not already visible and the marquee will be moved to the appropriate cell.

If the current cell is being edited, then the contents of the cell will be verified and the edit will be completed before moving the cell pointer.  If the validation for the current cell fails (due to the Validate event), then the cell pointer will not  be changed and the RowIndex will remain the same as it was before this call was made.

If the value of RowIndex is zero, it indicates an empty selection set in database mode, or the absence of data in callback mode.

In database mode, the current value of the Rows property may not reflect the actual number of rows in the database.  In such cases, it is possible to set RowIndex to a value which is larger than the actual number of rows in the current database or subset.  If you set RowIndex to a value larger than the number of actual rows, the grid will attempt to position the database to the newly selected row.  If the set does not contain the given number of rows, the grid automatically sets Rows and RowIndex to their correct values.

To TrueGrid, the term row number refers to the row within the overall set of data being browsed, rather than the screen row number.  Whether in callback or database mode, row 1 does not refer to the topmost row of the displayed grid, but refers to the first row of data.  A grid may contain thousands or even millions of rows.


Grid Rows Property

See Also	Example	Group

Usage	grid.Rows =longexpression

Read/Write at run time.  Not available at design time.

Property is global.

Description	This property defines the number of rows in the overall set of data being browsed.  If set to zero, no data is shown, although column headings will be displayed if they are enabled and there is at least one column.

To TrueGrid, the value of Rows refers to the number of rows in the overall set of data being browsed, rather than the number of rows displayed on the screen.  Whether in callback or database mode, row 1 does not refer to the topmost row of the displayed grid, but refers to the first row of data.  A grid may contain thousands or even millions of rows.

In callback mode, the grid will be repainted if this property changes the number of rows which are visible on the display.  In addition, the scrollbars will be adjusted to reflect the relative position of the current row with respect to the number of total rows.  If the scrollbars are no longer needed they will be removed, and if not present, they will be made visible if now required.

In database mode, this property is maintained by the grid and cannot be changed.  Under many circumstances, however, this value will not reflect the actual number of rows in the database.   This is because the grid itself does not attempt to determine how many database rows there are until absolutely necessary.  Why?  Because many queries (and database file formats) often require a great deal of work to determine how many rows there are.

For example, if a database contains 10,000 records, and you perform a text search query, all the records in the database must be scanned to find the matching rows.  If there are 1,000 matches, the grid would need to complete the entire query in order to set the Rows property to the correct value.

Instead, the grid will simply set the row number to a very large value (currently 1,000,000) until it encounters the last record in the set, at which point it will change the Rows property to contain the correct value automatically.


Grid SelectedBackColor Property

See Also	Example	Group

Usage	grid.SelectedBackColor = colorvalue

Read/Write at design time and run time.

Split-specific property.

Description	This property denotes the background color to be used for rows which have been selected by the user, or have been added to the BookmarkList.  The default setting is black.  Selected rows will only appear if SelectMode is set to one (1)or three (3).

You can set this color by clicking on the ellipsis in the properties window.  A color palette will appear which allows you to select a color.  You can also type the hexadecimal value of a color directly into the settings box.

The grid applies color using an attribute precedence scheme.  Attribute precedence is the order in which color and font properties are applied to the grid.  The precedence for SelectedBackColor is three (3).


Grid SelectedForeColor Property

See Also	Example	Group

Usage	grid.SelectedForeColor = colorvalue

Read/Write at design time and run time.

Split-specific property.

Description	This property denotes the foreground color to be used for rows which have been selected by the user, or have been added to the BookmarkList.  Default setting is black.  Selected rows will only appear if SelectMode is set to one (1)or three (3).

You can set this color by clicking on the ellipsis in the properties window.  A color palette will appear which allows you to select a color.  You can also type the hexadecimal value of a color directly into the settings box.

The grid applies color using an attribute precedence scheme.  Attribute precedence is the order in which color and font properties are applied to the grid.  The precedence for SelectedForeColor is three (3).


Grid SelectMode Property

See Also	Example	Group

Usage	grid.SelectMode = numericexpression

Read/Write at design time and run time.

Split-specific property.

Values	0 - Disabled (default)
1 - Enabled
2 - Disabled & Hidden
3 - Enabled & Hidden

Description	SelectMode specifies whether or not the selection is visible, and whether the user may select and deselect rows using the mouse.  By default, selections are visible, but the user may not select rows.  All rules apply to setting selected rows from code as well.

The SelectMode property has 4 possible values:

0 -	Disabled.  This is the default.  The user cannot select rows using the mouse.  However, if there is an existing selection present (such as one created by adding to BookmarkList), then it will be displayed.

1 -	Enabled.  The user can select rows using the mouse, and any selected rows are displayed.

2 -	Disabled & Hidden.  Like Disabled, the user cannot select rows.  In addition, any existing selection will not be visible.  However, the selection is maintained internally.

3 -	Enabled & Hidden.  An odd setting, where the user may select rows, but they won't be shown.  If you find a use for this, let us know.

Changing the value of SelectMode at runtime will cause the selection to be hidden or shown if necessary.


Grid SelectZoneWidth
Grid SelectZoneWidth Property

See Also	Group

Usage	grid.SelectZoneWidth = pixels

Read/Write at design time and run time.

Property is split-specific

Description	This property allows you to set the size of the zone in which the grids multiple selection checkmark will appear.  The number refers to the number of pixels from the lefthand border in which the checkmark will be displayed.  The default value is 6.

Note that while you can set this value to be as large as the first column or even larger, while the checkmark is displayed you cannot change the current row.  A good use of this is to change the zone width to the entire grid during a period when you only want them to select records and set it back normal when you want them to be able to edit and change rows.


Grid SelLength, SelStart, and SelText Properties
Grid SelLength, SelStart, SelText Properties

See Also	Group

Usage	grid.SelLength = integerexpression
grid.SelStart = integerexpression
grid.SelText = stringexpression

Read/Write at run time.  Not available at design time.

Property is global.

Description	These properties are identical to their counterparts in Visual Basic text controls, and apply to the grid's text editing window.  When the user has selected text for editing, these properties return the length of the selected text, the start of the selection, and the actual text contents of the selection.

If no cell is currently opened for editing, and only the marquee is present, then SelLength and SelStart will always return zero, and SelText will return an empty string.

Note that the color of the edit area may have to be changed using EditForeColor and EditBackColor for the selection to become visible.  This is because the default editing color is the same as the highlight color.


Grid SetStatusAttr Property

See Also	Example	Group

Usage	grid.SetStatusAttr = numericvalue

Write only at run time.  Not available at design time.

Split-specific property.

Values	GFS_CURCELL = &H1	'Current cell

GFS_HIGHROW = &H2	'Highlighted row

GFS_CHANGED = &H4	'Updated cell

GFS_SELECTED = &H8	'Marked row

 0 	'Cells with none of the above status types

Description	This property allows you to control the color of a cell based on the assigned cell status.  Before this property is set to the specified cell status, the programmer must also set three additional properties:  ParamBackColor, ParamForeColor, and ParamFontStyle,

The assigned cell status determines the condition that must be satisfied before the color attributes will be applied to a given cell - the cell status must match with the SetStatusAttr value.  If this condition is satisfied, then ParamBackColor, ParamForeColor, and ParamFontStyle will be applied when displaying the cell.

There are four (4) basic cell status (GFS_CURCELL, GFS_HIGHROW, GFS_CHANGED, GFS_SELECTED).  A cell can have any of the sixteen (16) possible combinations of the four basic status.  Simply add (or use the VB Or operator) to combine the values of the applicable basic status to get the cell status you want.  For instance, to indicate a cell is Selected and also Current, use a cell status value equal to GFS_CURCELL Or GFS_SELECTED, this could also be expressed as &H9.

A SetStatusAttr of zero (0) applies to all cells which do not have any of the four basic status.

Every time this property is set, the SetStatusAtttr condition is added to the list of existing conditions.  Hence, by repeated use of this property it is possible to set up multiple conditions to affect the display appearance of the grid.

If one of the Param properties is not set before calling SetStatusAttr it will use the previous setting for that property.  If the Param property has never been set then it will inherit the existing grid property.  It is best to explicitly set all four Param properties before each call so that you dont get unexpected behavior.

The grid applies color using an attribute precedence scheme.  Attribute precedence is the order in which color and font properties are applied to the grid.  The precedence for SetStatusAttr is five (5).

This property can only be written to and cannot be read.  If you attempt to read this property at run-time an error will occur.


Grid SplitAtPoint Property

See Also	Example	Group

Usage	integervar = grid.SplitAtPoint

Read-only at run time.  Not available at design time.

Property is global.

Description	Returns the split which is beneath the point specified by PointX and PointY.  If there is no split at that position, then this property returns zero (0).

This property and other cell and column dimension and location properties enable you to easily implement some useful location-specific features.  Examples might be drag and drop, popping up balloon help, or other controls such as a combo box or your own edit window.


Grid SplitEditable Property

See Also	Example	Group

Usage	boolean = grid.SplitEditable

Read/Write at design time and run time.

Split-specific property.

Description	This property defaults to True.  When set to False, it disables the ability to edit the current split.

If there is only one split then setting this property has the same affect as setting the Editable property of the grid.  If the Editable property of the grid is set to False, then entire grid is disabled for editing, regardless of this setting.


Grid SplitGroup Property

See Also	Example	Group

Usage	grid.SplitGroup = integerexpression

Read/Write at design time and run time.

Split-specific property.

Description	The SplitGroup property allows you to group the behavior of vertical scrolling.  All splits with the same SplitGroup setting will be synchronized when vertical scrolling occurs.  Splits belonging to different groups can scroll independently, allowing different splits to display different parts of the database.

If the vertical scrollbar setting is "Automatic", then only the rightmost split of the group will have a vertical scrollbar.  If there is only one split then setting this property has no effect on the behavior of the grid.

Setting any of the row index specific properties like RowIndex or TopRow will affect all splits in the given group.  This keeps the group synchronized.


Grid SplitIndex Property

See Also	Example	Group

Usage	grid.SplitIndex = integerexpression

Read/Write at design time and run time.

Property is global.

Description	This property returns the number (index) of the current split.  You can set this value at run time to change the current split to the specified index.  If SplitPropsGlobal is set to False then all properties marked as split-specific will only be set for the current split.

You can also set this property at design time.  When changing the SplitIndex at design time it will change all the split-specific properties in the properties window to their settings for that split.

At run time the user can change this value by clicking on a different split with the mouse.  If you don't want the user to be able to change the current split then set the SplitSelectable properties of all other splits to False.

This property allows you to set Split specific properties for several different splits at run-time without requiring the user to have that split be current.  You can change the current split using the SplitIndex and then change it back after you set the appropiate properties.


Grid SplitLocked Property

See Also	Example	Group

Usage	grid.SplitLocked = boolean

Read/Write at design time and run time.

Split-specific property.

Description	Setting this property to True will prevent the user from resizing the current split.  If all splits are locked, the user will not be able to create new splits interactively.

By default this property is set to False which would allow the user to interactively resize the split or create a new one from the leftmost unlocked split.

  Don't confuse locked splits with locked columns.  They are quite different.  Locked columns refer to TrueGrid's ability to place columns in a stationary position at the left of the grid.  Locked splits refer to this property, which controls a split's configurability by the user.


Grid SplitPropsGlobal Property

See Also	Example	Group

Usage	grid.SplitPropsGlobal = boolean

Read/Write at design time and run time.

Property is global.

Description	This property allows you to define the behavior when setting split-specific properties.  If this property is set to True then every property marked as split-specific will apply to all existing splits.

If this property is set to False then the split-specific properties will apply only to the current split (returned by SplitIndex).

Whether or not you set this property depends upon your needs.  Leaving the property set to True simplifies using most of the grid properties and allows you to simply and easily configure the entire grid.  If however you are going to need more control over multiple split colors, locking, grouping, etc., then you will probably need to set this property to False.


Grid Splits Property

See Also	Example	Group

Usage	grid.Splits = integerexpression

Read/Write at run time.  Not available at design time.

Property is global.

Description	At run time you can use this value to add another split or to query the number of splits currently in existance.  This property returns an integer that corresponds to the number of splits currently displayed in the grid.  You can use this property to track the number of splits that the user has created.

Setting Splits to a value one greater than the current number of splits will automatically add a new split.


Grid SplitSelectable Property

See Also	Example	Group

Usage	grid.SplitSelectable = boolean

Read/Write at design time and run time.

Split-specific property.

Description	If this property is set to False for the current split then the user will be unable to interactively select that split.  When clicked on, the split will not recieve focus and the previous control that had focus will retain focus.

Using this property in combination with the SplitLocked property allows you to completely prohibit the user from making any changes to the specified split.  Unselectable splits are passed over when SplitTabMode is set to one (1).


Grid SplitSize Property

See Also	Example	Group

Usage	grid.SplitSize = integerexpression

Read/Write at design time and run time.

Split-specific property.

Description	This property returns the size of the current split.  The meaning of the value returned by SplitSize is determined by the SplitSizeMode.

If the SplitSizeMode is set to 1 - Exact then the integer SplitSize value returned will be the size of the split in Twips.  If the SplitSizeMode is set to 2 - Number of columns, then the split will adjust to display the number of full columns specified in SplitSize.  If the SplitSizeMode is 0 - Scalable (default) then the number returned by SplitSize is a number which indicates the relative size of all scalable splits.


Grid SplitSizeMode Property

See Also	Example	Group

Usage	grid.SplitSizeMode = numericexpression

Read/Write at design time and run time.

Split-specific property.

Values	0 - Scalable

1 - Exact(twips)

2 - Number of columns

Description	This property determines how the SplitSize property is used to determine the actual size of a split.

If the SplitSizeMode is set to 1 - Exact then the integer SplitSize value returned will be the size of the split in Twips.  It also allows you to fix the size of the split.  If more splits are added a split with this setting would not be resized to accommodate the new split.

If the SplitSizeMode is set to 2 - Number of columns, then the split will adjust to display the number of full columns specified in SplitSize.  For example, if the SplitSize is set to two (2), when the split scrolls, it will always display exactly two (2) columns no matter what the size of the two visible columns are.

If the SplitSizeMode is 0 - Scalable (default) then the number returned by SplitSize is a number which indicates the relative size of all scalable splits.  For example, if there are 3 scable splits with SplitSize properties equal to  1, 2, and 4, then the size of the column would be a fraction of the total grid width 1/8, 1/4, 1/2, respectively.

Consider a grid containing both scalable splits and splits with fixed number of columns.  As the splits with fixed number of columns scroll, the total size remaining for the scalable splits may change because grid columns are generally of different widths.  But the ratios of the sizes of the scalable splits remain the same as specified by the SplitSize properties.

If you set the sizes of the scalable splits interactively at design time using the Layout Editor, then the grid calculates the SplitSize values according the relative sizes of the splits.


Grid SplitTabMode Property

See Also	Example	Group

Usage	grid.SplitTabMode = numericexpression

Read/Write at design and run time.

Property is global

Description	This property determines how the Tab and arrow keys will behave at split borders.  It does not determine if the tab and arrow keys will move from cell to cell, or from control to control, or wrap.  That will be determined by the AllowArrows, AllowTabs, WrapCellPointer, and TabCapture properties.  If the tab and arrow keys are able to move from cell to cell, SplitTabMode determines whether they will move across split boundaries to adjacent splits.

When set to zero (0) , the default, the tab and arrow keys will not move the current cell across split boundaries.  They will either wrap, stop, or move to other controls depending on the values of WrapCellPointer and TabCapture.

When set to one (1) , the tab and arrow keys will not move the focus across split boundaries.  When at the last column of the rightmost split (or the first column of the leftmost split), they will either wrap, stop, or move to other controls depending on the values of WrapCellPointer and TabCapture.


Grid TabCapture Property

See Also	Example	Group

Usage	grid.TabCapture = boolean

Read/Write at design and run time.

Property is global

Description	If False, the default, the Tab key can exit the grid and move to another control.  If AllowTabs is True, you can use the tab key to move from cell to cell within the same row.  When the current cell pointer reaches the grid border, the tab key will exit the grid and set focus to the next control.

If True, then the Tab key will never exit the grid once it has focus.  If AllowTabs is True, you can use the tab key to move from cell to cell within the same row.  When the current cell pointer reaches the grid border, the tab key will not be able to exit the grid and the current cell will stop at the grid border.

If there are splits present and TabCapture is False, and SplitTabMode is 0, then the tab key will exit the current split and move to the next (or previous) control.


Grid Text Property

See Also	Example	Group

Usage	grid.Text = stringexpression

Read/Write at run time.  Not available at design time.

Split-specific property

Description	The Text property may be used to retrieve or set the contents of the current cell being edited by the user.  It has no effect upon the data in the database, and does not cause the Validate or Update events to be sent under any circumstances

If the current cell is currently open for editing by the user, then this property returns the text they are currently working on.  If the Text property is set, then the information in the edited cell will change to match the new value and the old text will be lost.  As stated, Update and Validate will not be triggered.

If the current cell is not being edited (the marquee is displayed around the current cell), then this property will return the visible contents of the current cell.  This may not  be the value stored in the database, since the grid does not refresh its display until it receives control during the idle loop.  Thus, the following sequence of steps will not work as expected:

' Open a file and attempt to fetch cell data

Data1.DatabaseName = "BIBLIO.MDB" ' grid using ds=Data1

Data1.RecordSource = "Titles"

Data1.Refresh

Grid1.RowIndex = 1

Grid1.ColumnIndex = 1

dataval$ = Grid1.Text	' will not work

If you assign to the Text property while the current cell is not being edited, then the grid will enter edit mode immediately and set the current cell data to the new value of the Text property.  Thus, the following line of code will cause the grid to enter editing mode immediately:

Grid1.Text = Grid1.Text

A better way to do this however is to start editing in the EditActive.

If the current cell is not visible when the assignment occurs, the grid will be scrolled so that the cell is visible before edit mode is entered.

Attempting to manipulate the current cell has its limitations.  The grid will leave editing mode automatically under many circumstances (such as when focus is lost).  Therefore, code which manipulates the current cell being edited shouldnt be used in contexts where focus might be lost easily (such as in another button on the form).


Grid TopRow Property

See Also	Example	Group

Usage	grid.TopRow =integerexpression

Read/Write at run time.  Not available at design time.

Split-specific property

Description	This property denotes the one-based index of the topmost grid row.  You can use this property to scroll the grid vertically in code at run time just as the RowIndex property can be used to scroll the grid vertically.

To the grid, the term row number refers to the row within the overall set of data being browsed, rather than the screen row number.  Whether in callback or database mode, row one (1) does not refer to the topmost row of the displayed grid, but refers to the first row of data.  A grid may contain thousands or even millions of rows.

In database mode, it is possible to set TopRow to a value larger than the actual number of rows in the database if the values of Rows is not known.  In this case it will find the largest possible value by determining Rows.  See the description of Rows and RowIndex for a discussion of how database mode treats the row number and row count.


Grid VertColor Property

See Also	Example	Group

Usage	grid.VertColor = colorvalue

Read/Write at design time and run time.

Split-specific property

Description	This property denotes the color of the grid's vertical lines.  This property defaults to the System Windows Frame Color (0x800000006).  This color is only meaningful if vertical lines are turned on, via the VertLines property.

You can set this color by clicking on the ellipsis in the properties window.  A color palette will appear which allows you to select a color.  You can also type the hexadecimal value of a color directly into the settings box.


Grid VertLines Property

See Also	Example	Group

Usage	grid.VertLines = numericexpression

Read/Write at design time and run time.

Split-specific property

Values	0 - None (default)
1 - Single
2 - 3D

Description	This property determines whether the grid displays vertical lines between columns.

If the value of this property is 0 - None, then no lines are displayed.  If the value is 1 - Single, then single-width lines are displayed in the color specified by VertColor.

If the value of this property is 2 - 3D, then the grid will attempt to draw the lines in 3D mode.  The grid uses the VertColor value for the darker border of the 3D "groove" between cells, and chooses another color from the available colors in the system palette.  Some experimentation is usually required to achieve the desired effect.  The standard grey 3D effect is chosen by selecting a dark grey color for the lines and a medium grey for the grid background color.


Grid VertScrollbar Property

See Also	Example	Group

Usage	grid.VertScrollbar = numericexpression

Read/Write at design time and run time.

Split-specific property

Values	0 - None

1 - Always

2 - Automatic

Description	This property determines the status of the vertical scrollbar.  By default this property is set to 2 - Automatic.  In this mode the grid displays the scrollbar based on whether there is enough room to display all the rows.  If the number of rows exceeds the total number of displayed rows then the scroll bar will appear, otherwise it will not.

If this property is set to 1 - Always then the vertical scrollbar will always appear regardless of whether or not all the rows fit into the grid display area.

When set to 0 - None the vertical scrollbar is never displayed.  It is important to note that if you have this setting and there are more rows then the grid can display, the user will only be able to acces the additional rows by using the keyboard navigation keys.

When there are multiple splits, TrueGrid automatically chooses the location for the vertical scrollbar whenever VertScrollbar is set to "2 - Automatic".  In such cases, TrueGrid displays the vertical scrollbar only on the rightmost split of each split group (see SplitGroup).


Grid Version Property

See Also	Example	Group

Usage	integervar = grid.Version

Read only at run time.  Not available at design time.

Property is global

Description	In general, only the published version number is of interest to TrueGrid developers, and therefore this function should rarely be used.  However, in some circumstances, especially when Apex ships patched or minor updates, this number is useful.  Such cases occur when a feature is added or a bug is changed and an application depends upon it.  You can use the Version property to assure that your users are running the proper upgraded or patched version of the VBX to avoid any headaches which can occur from subtle version differences.

Checking this property is recommended if applications rely on a particular version and want to protect their users from running the application with the wrong VBX.


Grid VlistColumn Property

See Also	Example	Group

Usage	grid.VlistColumn = integerexpression

Read/Write at run time.  Not available at design time.

Property is global

Description	This property returns the number (index) of the current value list column.  You can set this value at run time to change the current value list column.

This property allows you to set value list specific properties (VlistCount, VlistData, VlistDefault, VlistPicture, VlistStyle and VlistText) for several different columns.  You can use this property at run time to change attributes of any of the value list properties for the given column


Grid VlistCount Property

See Also	Example	Group

Usage	grid.VlistCount = integerexpression

Read/Write at run time.  Not available at design time.

Property is global

Description	This property specifies the current number of items in the current value list, as specified by VlistColumn.  It can only be assigned to zero (0) in order to clear the current value list.  If VlistCount is set to zero, the VlistStyle property will be ignored and the grid will behave as though no value list has been defined (i.e., field data from the database or calculated values will be displayed).  Attempting to set this property to a value other than zero (0) will result in an error.


Grid VlistData Property

See Also	Example	Group

Usage	grid.VlistData(index) = stringexpression

Read/Write at run time.  Not available at design time.

Property is global.

Description	The index value ranges from 1 to the VlistCount property value for the column specified by VlistColumn.  Setting this property at runtime is equivalent to specifying the values in the "Data" column of the Field Values... dialog at design time.  To add a new "Data" item, use an index value of one plus the current VlistCount value.  You can replace an existing VlistData(index) with a new stringexpression, but you cannot delete an existing VlistData(index) item at runtime.  (You can only delete a value list item at design time in the Field Values... dialog using the Delete key.)

Using this property in conjuction with VlistStyle, VlistText, and VlistPicture it is possible to create a value list at run-time.


Grid VlistDefault Property

See Also	Example	Group

Usage	grid.VlistDefault = integerexpression

Read/Write at run time.  Not available at design time.

Property is global.

Description	The VlistDefault value can be any value from 0 to the VlistCount property value  for the column specified by VlistColumn.  Setting this property at runtime is equivalent to checking the "Default Value" box of the Field Values... dialog at design time.

If this property is set and the grid attempts to display a value which is not in the value list, then the corresponding value from VlistData will be displayed.

Table1.VlistColumn = 2

Table1.Data(1) = " 0"

Table1.Data(2) = "-1"

Table1.Data(3) = "99"

'Default value for column 2 will be 99

Table1.Default = 3

Setting this property to zero (0) means there will be no default display value (or the default value for vlist column is disabled).


Grid VlistPicture
Grid VlistPicture Property

See Also	Example	Group

Usage	grid.VlistPicture(index) = picture

Read/Write at run time.  Not available at design time.

Property is global.

Description	The index value ranges from 1 to the VlistCount property value for the column specified by VlistColumn.  Setting this property at runtime is equivalent to pasting a picture in the "User Value" column of the Field Values... dialog at design time.  To add a new "User Value" item, use an index value of one plus the current VlistCount value.  You can replace an existing VlistPicture(index) with a new picture, but you cannot delete an existing VlistPicture(index) item at runtime.  (You can only delete a value list item at design time in the Field Values... dialog using the Delete key.)  This property is only accessed when the VlistStyle property is set using the GVLS_TRANSLATE option.


Grid VlistStyle Property

See Also	Example	Group

Usage	grid.VlistStyle = integerexpression

Read/Write at run time.  Not available at design time.

Property is global.

Description	This property allows you to set the "Display values", for the column specified by VlistColumn.  Using this property you can also set the following conditions for a value list column:  "Sorted", "Translate Values", "Auto Validate" and "Cycle on Click".  These values directly correspond to the options you can set in the Field Values... dialog at design time.

The constants required to specify the VlistStyle property are defined in the TGCONST.TXT file in your TrueGrid installation directory.

The "Display values" or the cell display type has three (3) possible settings:

GVLS_TEXT (0)	to display text or picture in the cell

GVLS_COMBO (1)	to drop down the built-in combo box in the cell

GVLS_RADIO (2)	to display built-in radio buttons in the cell

Programmers can use GVLS_MASK (&HF) to extract the cell display type from the VlistStyle property.

The "Sorted", "Translate Values", "Auto Validate" and "Cycle on Click" values can be specified using the following constants:

GVLS_SORTCOMBO (&H80)	sort the values in the drop down combo

GVLS_TRANSLATE (&H10)	substitute Data values for User values

GVLS_VALIDATE (&H20)	allow only valid values to be entered

GVLS_CYCLE (&H40)	cycle through all specified values

Programmers can combine any one of the "Displayed values" with one or more of the "Sorted", "Translate Values", "Auto Validate" and "Cycle on Click" values.  For example, for column 3 to display radio buttons using "Translate Values" and "Cycle on Click":

Table1.VlistColumn = 3

Table1.VlistStyle = GVLS_RADIO Or GVLS_TRANSLATE Or GVLS_CYCLE


Grid VlistText Property

See Also	Example	Group

Usage	grid.VlistText(index) = stringexpression

Read/Write at run time.  Not available at design time.

Property is global.

Description	The index value ranges from 1 to the VlistCount property value for the column specified by VlistColumn.  Setting this property at runtime is equivalent to specifying textual values in the "User Value" column of the Field Values... dialog at design time.  To add a new "User Value" item, use an index value of one plus the current VlistCount value.  You can replace an existing VlistText(index) with a new stringexpression, but you cannot delete an existing VlistText(index) item at runtime.  (You can only delete a value list item at design time in the Field Values... dialog using the Delete key.)  This property is only accessed when the VlistStyle property is set using the GVLS_TRANSLATE option.


Grid WrapCellPointer Property

See Also	Example	Group

Usage	grid.WrapCellPointer = boolean

Read/Write at design and run time.

Property is global

Description	This property determines the behavior of the arrow keys if AllowArrows is True.  If WrapCellPointer is True, then the cell pointer will wrap from the last column to the first in the next row (or from the first column to the last in the previous row).  If WrapCellPointer is False, the cell pointer will not wrap to the next (or prevous) row, but will stop at the last (or first) column of the current row.

If SplitTabMode is set to zero (0), the cell pointer will wrap only within the current split.  If SplitTabMode is set to one (1), then the cell pointer will move from one split to the next before wrapping occurs.

If TabCapture is set to True, then the tab key will behave identically to the arrow keys, and will automatically wrap to the next or previous cell.


Grid Standard Properties

Standard Properties

The grid also supports the following standard Visual Basic properties.  Consult the Visual Basic documentation for details.

BackColor	BorderStyle	DragIcon	DragMode

Enabled	FontBold	FontItalic	FontName

FontSize	FontStrikeThru	FontUnderLine	ForeColor

Height	Hwnd	HelpContextId	Index

Left	MousePointer	Name	TabIndex

TabStop	Tag	Top	Visible

Width


Grid Append Event

See Also	Example	Group

Syntax	Grid_Append()

Description	This event is sent whenever the user is at the bottom row of data in the grid, and they attempt to move down one more row by using the down arrow key.  Additional this event is now fired when you attempt to scroll past the last row using the mouse

This event will be triggered if (a) AddNew is in progress AND (b) no data has been modified in the current row.

This event can be used to implement dBASE-like append behavior, where a record is automatically added if you are at the last row of the grid and you attempt to move down further.  By putting an AddNew method in this event you can allow the user to add a new record to the database.  If no changes are made to the new record and the user moves off the row then the grid not add the new record and automatically delete the temporary record.

If this event is not implemented, then the grid takes no action whatsoever if an attempt is made to move beyond the last row of data.  The marquee or editing area remains at the same location.


Grid CellChange Event

See Also	Group

Syntax	Grid_CellChange()

Description	This event is sent whenever the current cell position is changed.  The event is sent under several circumstances:

1.	When the grid is first displayed.

2.	When the user moves the cell pointer by using the mouse or the keyboard.

3.	When data in the grid is changed and causes the cell to change implicitly (such as when the last record in a set is deleted, and the cell was currently positioned on the same row).

4.	When the RowIndex or ColumnIndex properties are set to a different value than they currently have.

Typically, the RowIndex and ColumnIndex properties are used to determine the new cell number.  In some cases, this event is triggered with a RowIndex or ColumnIndex property value of zero.  These circumstances occur when there are no rows in the grid at all.

When multiple events are sent, the order will be Change, RowChange, ColumnChange, and finally CellChange.  None of these events will be sent until the data has been validated using the Validate event.


Grid Change Event

See Also	Group

Syntax	Grid_Change()

Description	This event is triggered each time the user changes text in the text editing window.  Just as with the Visual Basic Text control, each keystroke causes a Change event to be triggered.

This event is never sent when editing is not in progress.

When multiple events are sent, the order will be Change, RowChange, ColumnChange, and finally CellChange.  None of these events will be sent until the data has been validated using the Validate event.


Grid CheckRows Event

See Also	Group

Syntax	Grid CheckRows(RequestRows As Long, CurRows As Long)

Description	This event, has been added for use only in callback mode.  If the number of rows is unknown then you can set the number of rows in the CheckRows event.  TrueGridfires the CheckRows event before it scrolls to a new position in the database.

RequestRows will contain the highest row number TrueGrid wants to display.  For example, when you scroll down or page down, TrueGrid determines what the new bottom row displayed would be, and RequestRows is then set to that value.

CurRows contains the number of rows currently defined for the grid (previously using Rows).  This value may be changed within the event to indicate a new row count.  Within CheckRows you may increase the number of rows, or decrease them.  TrueGrid will automatically adjust all internal structures to reflect the change.

CheckRows will always be called before Fetch is called.  Thus, so long as CheckRows assures that the requested row exists, or modifies CurRows accordingly, Fetch will never be called with a non-existent row number.


Grid ClickButton Event

See Also	Example	Group

Syntax	Grid_ClickButton()

Description	This event is triggered when the built-in button in a cell is clicked (see the ColumnButton property).  You generally display the button in a cell if you want to drop down a Visual Basic control (such as the built-in combo box or a bound list box) for editing or data entry.  When the button in the current cell is clicked, the ClickButton event will be fired.  You can then write code to drop down the desired control from the cell


 Grid ColumnChange Event

See Also	Example	Group

Syntax	Grid_ColumnChange()

Description	This event is sent whenever the current column number is changed.  The event is sent under several circumstances:

1.	When the grid is first displayed.

2.	When the user moves to a new column by using the mouse or the keyboard.

3.	When the ColumnIndex property is changed to a different value than it currently has, or the ColumnVisible property for the current column is set to FALSE.

4.	If the current column size is decreased so that it no longer appears at all.

Typically, the RowIndex and ColumnIndex properties are used to determine the new cell number.  In some cases, this event is triggered with a RowIndex or ColumnIndex property value of zero.  These circumstances occur when there are no rows in the grid at all.

When multiple events are sent, the order will be Change, RowChange, ColumnChange, and finally CellChange.  None of these events will be sent until the data has been validated using the Validate event.


Grid ColumnSumChange Event

See Also	Example	Group

Syntax	ColumnSumChange(Col As Integer)

Description	TrueGrid automatically fires this event whenever it detects a change in the total sum value for a column which has summary capabilities enabled.

This event will be fired when:

1.	ColumnSumEnable is first set to True for any column.

2.	The user changes data in the grid interactively, thereby affecting the column sum.  Changes to the current record are reflected in the sum immediately, rather than when they are written to the database.

3.	Your program changes data in the database, thereby changing the column sum.  TrueGrid monitors database activity to detect such changes.

4.	Database operations such as Refresh and Rollback trigger this event, since the column summary may have changed (TrueGrid has no way of knowing, since changes may have occurred elsewhere on a network).

Typically, you write code in this event to display the column total elsewhere on your form, or to use the total in a calculation.  You can access the current column sum using the ColumnSum property, as in the following example:

Sub Table1_ColumnSumChange(Col As Integer)

' Display the average

AvgBox.Caption = Table1.ColumnSum(Col) / Data1.Recordset.RecordCount

End Sub


Grid ComboSelect Event

See Also	Example	Group

Syntax	Grid_ComboSelect()

Description	When using a column with a VlistStyle of GVLS_COMBO the ComboSelect event will be fired whenever the user has selected (by clicking) one of the combo items, but has not yet left cell editing mode.

This event is useful for determining the contents of the cell before the user leaves editing.  With this event you can force the grid to leave editing without allowing the user a chance to edit his selection.


Grid DragCell Event

See Also	Example	Group

Syntax	Grid_DragCell(Split as Integer, Row as Long, Col as Integer)

Description	This event is triggered when the user presses down with left mousebutton and starts dragging the mouse.  This event is used to notify the programmer when the user wants to start a drag-and-drop operation.  Using the Split, Row, and Col parameters you can determine the exact location of the mouse pointer at the start of the drag-and-drop operation.

You can start dragging in this event either automatically, by intiating the Drag method of the grid.


Grid EnterEdit Event

See Also	Example	Group

Syntax	Grid_EnterEdit()

Description	This event is triggered whenever a cell is opened for editing.  The cell can be opened for editing by typing a character (which overwrites the current contents), clicking on the cell with the mouse, or by assigning to the Text property.

When editing is completed, Validate and Update are called if the data has been changed.  Then, the ExitEdit event will be called to indicate that editing is completed.


Grid ExitEdit Event

See Also	Example	Group

Syntax	Grid_ExitEdit()

Description	When editing is completed in a grid cell, this event is triggered.  The event will be triggered regardless of whether any changes have been made to the cell.

Before ExitEdit is triggered, the Validate and Update events will be called if the cell contents have been changed.


Grid Fetch Event

See Also	Example	Group

Syntax	Grid_Fetch(Row As Long, Col As Integer, Value As String)

Description	In callback mode, this event is sent whenever the grid needs to display the contents of a cell.  Just set the Value parameter to the desired string value.

In database mode, this event is not sent.


Grid FetchAttributes Event

See Also	Example	Group

Syntax	Grid_FetchAttributes(Status As Integer, Split as Integer, Row as Long, Col as Integer, FgColor As Long, BgColor As Long, FontStyle as Integer)

Description	This event allows you complete control over the appearance of the grid.  This event is called for every column that has had it's ColumnCellAttrs property set to True.  This event gives you tremendous flexibility.  For example, in this event you can check for a range of values and display them in a different color or font.  Or use different colors to warn or bring the user's attention to a critical condition.

Often you will want to inspect the value of the cell that the fetch event is being called for.  The ColumnText property referenced with the Col parameter allows you to check the contents of the current cell.  This also gives you the ability to inspect values from other columns.

The Status parameter is one of 16 possible combinations that represent the status of the current cell (see ParamStatus).  Split is the current split for which the FetchAttributes event is being called.  FgColor is the ForeColor, BgColor is the BackColor, and FontStyle is the FontStyle (see ParamFontStyle) that will be used when displayng the cell.

Remember that for each column where the ColumnCellAttrs is set to True, the FetchAttributes event will be called for each cell display.  If at all possible it is recommended that you use ColumnAddRegexAttr, ColumnSetStatusAttr, AddRegexAttr, or SetStatusAttr to control individual cell colors because these properties are maintained internally and hence considerably faster than using the FetchAttributes event.


Grid FetchMargins Event

See Also	Example	Group

Syntax	Grid_FetchMargins(Split As Integer, Row As Long, Col As Integer, InsetLeft As Integer, InsetRight As Integer)

Description	This event is triggered for any column that has it's ColumnFetchMargins property set to True.  By setting the InsetLeft and InsetRight parameters it is possible to have specified rows and columns indented from the left or right.  Both InsetRight and InsetLeft values are in tenths of a character.  If, for example, a column is left justified and InsetLeft is set to fifty (50) then the right hand side of the column text will be indented by five (5) characters.  If the InsetRight is set in this case then the column text would wrap 5 characters before the right hand vertical line.


Grid LeftColChange Event

See Also	Group

Syntax	Grid_LeftColChange()

Description	This event is sent whenever the left column number is changed.  The event is sent under several circumstances:

1.	When the grid is first displayed.

2.	When the user moves to a new column by using the mouse or the keyboard (e.g.scrolling the grid horizontally using the scrollbar).

3.	When the LeftColumn property is changed forcing a new left column to be displayed.

4.	The ColumnVisible property for the current left column is set to False.

5.	If the current left column's size is decreased so that it no longer appears at all.

Typically, the RowIndex and ColumnIndex properties are used to determine the new cell number.  In some cases, this event is triggered with a RowIndex or ColumnIndex property value of zero.  These circumstances occur when there are no rows in the grid at all.

When multiple events are sent, the order will be Change, TopRowChange, LeftColChange, RowChange, ColumnChange, and finally CellChange.  None of these events will be sent until the data has been validated using the Validate event.


Grid LayoutChange Event

See Also	Example	Group

Syntax	Grid_LayoutChange (Action As Integer, Split As Integer, Col As Integer)

Description	The LayoutChange event is fired to indicate that (a) the user has made interactive changes to splits or columns, (b) a fresh layout has been automatically read from the database, and (c) the Layout or LayoutIndex properties have been set.

LayoutChange has three arguments:  Action, Split, and Col.

Action contains one of the following values (defined in TGCONST.TXT):

GLCH_SPLITCREATE (0)	The user has created a new split with the split bar.

GLCH_SPLITDELETE (1)	The user has deleted a split by dragging it to the far right or left.

GLCH_SPLITADJUST (2)	The user has resized one of the splits.

GLCH_COLMOVE (3)	The user has shuffled a column to a new position.

GLCH_COLRESIZE (4)	The user has resized a column.

GLCH_COLHIDE (5)	The user has resized a column to nothing (hiding it).

GLCH_DATABASE (6)	The layout has been read from the database.  This is fired whenever you Refresh the data control and there is no design-time layout.

GLCH_PROPERTY (7)	The complete layout has been changed as a result of modifying the Layout or LayoutIndex properties.

For Action=3, 4, and 5, the Split and Col arguments will contain the split and column number of the column which the user has adjusted. Note that the split number is not available for actions 0, 1, and 2, since more than one split is affected by those operations.

The most common use of this will be when the programmer wants to save the changes the user has made to the grid.  In this event he will save the new changes using the Layout property.


Grid MarkChange Event

See Also	Example	Group

Syntax	Grid_MarkChange(Row As Long, IsMarked As Integer)

Description	This event is called whenever a user marks or unmarks a row by moving the cursor to the left margin of the grid and clicking.  This event will be called only if user selection is enabled using the SelectMode property.

The Row argument will contain the row selected or deselected by the user.  The row number may not be the current row, since the user may select or deselect any visible row without changing the current row position.

The IsMarked argument will be True if the row is now selected.  This means that the user has just selected the row and it has been added to the BookmarkList.  IsMarked will be False if the row has just been deselected and removed from the BookmarkList.

In callback mode or if the current database is not bookmarkable, the IsMarked property will always be False.  This is because the grid is expecting you to maintain which rows are highlighted using the QueryMark event.


Grid QueryMark Event

See Also	Example	Group

Syntax	Grid_QueryMark(Row as Long, IsMarked as Integer)

Description	QueryMark is called when the DataMode is set to 1 - Application or if the current database is not bookmarkable, and if user selection is enabled using the SelectMode property.  This event allows for multiple selection in callback mode.  This event is called once per row in such cases where the grid needs to determine whether a given row is marked.

The grid uses bookmarks to maintian selected rows when the DataMode is set to database, however if the Data Controls Bookmarkable property returns False then the grid cannot use bookmarks to maintain the selections.  In this case the QueryMark and MarkChange events can be used exactly as you would use them in callback mode.

Setting IsMarked to True tells TrueGrid the row is selected.  It will highlight it if selection highlighting is enabled via SelectMode.  IsMarked always has an initial value of False, since your code determines the marked status of rows in callback mode.


Grid RequestEdit Event

See Also	Example	Group

Syntax	Grid_RequestEdit(Cancel As Integer, KeyAscii As Integer)

Description	This event is triggered just before the user enters edit mode.  Using the Cancel parameter it is possible to prevent the user from entering edit mode.  The KeyAscii parameter contains zero (0) if the user clicked the mouse to enter edit mode and the ASCII keycode if the user type a character from the keyboard.

A common use for this event is to detemine how the user entered edit mode.  If, for example, let's say you wanted to pop up a list box only if the user clicked on the current cell.  Simply check the value of KeyAscii first, set Cancel to True if it is zero (0) and then pop-up a list box.


Grid RowChange Event

See Also	Group

Syntax	Grid_RowChange()

Description	This event is sent whenever the current row position is changed.  The event is sent under several circumstances:

1.	When the grid is first displayed.

2.	When the user moves the cell pointer to another row by using the mouse or the keyboard.

3.	When data in the grid is changed and causes the row to change implicitly (such as when the last record in a set is deleted, and the cell was currently positioned on the same row).

4.	When the RowIndex property is changed to a different value than it currently has.

Typically, the RowIndex and ColumnIndex properties are used to determine the new cell number.  In some cases, this event is triggered with a RowIndex or ColumnIndex property value of zero.  These circumstances occur when there are no rows in the grid at all.

To TrueGrid, the value of RowIndex refers to the row within the overall set of data being browsed, rather than the screen row number.  Whether in callback or database mode, row 1 does not refer to the topmost row of the displayed grid, but refers to the first row of data.  A grid may contain thousands or even millions of rows.

This event should be used to determine when the user selects a new record.  Although the Click event can also be used, it is not as reliable, since it doesnt allow for keyboard activity.  Just before RowChange is triggered, ReferenceRow is reset to the value of RowIndex.

When multiple events are sent, the order will be Change, RowChange, ColumnChange, and finally CellChange.  None of these events will be sent until the data has been validated using the Validate event.


Grid SplitChange Event

See Also	Example	Group

Syntax	Grid_SplitChange()

Description	This event is called anytime the current split changes.  This can happen in several ways:

1.	If the user clicks on a split other than the current split

2.	If the split is changed via code using the SplitIndex property.

3.	If the current split is removed via code, or user interaction.

The importance of this event is to notify the programmer that the SplitIndex has changed and that setting any of the splittable properties will affect a different split.  It may be useful in a variety of other cases as well depending on your application.


Grid TopRowChange Event

See Also	Group

Syntax	Grid_TopRowChange()

Description	This event is sent whenever the current top row is changed.  The event is sent under several circumstances:

1.	When the grid is first displayed.

2.	When the user scrolls the grid with the vertical scrollbar

3.	When data in the grid is changed and causes the top row to change implicitly (such as when the first record in a set is deleted).

4.	When the TopRow property is changed to a different value than it currently has.

Typically, the RowIndex and ColumnIndex properties are used to determine the new cell number.  In some cases, this event is triggered with a RowIndex or ColumnIndex property value of zero.  These circumstances occur when there are no rows in the grid at all.

When multiple events are sent, the order will be Change, TopRowChange, LeftColChange, RowChange, ColumnChange, and finally CellChange.  None of these events will be sent until the data has been validated using the Validate event.


Grid UnboundFetch Event

See Also	Example	Group

Syntax	Grid_UnboundFetch (Row as Long, Col as Integer, BookMark as String, Value As String)

Description	If the DataMode property is 0 - Database Mode, then for all columns where the ColumnType properties are set to 1 - Unbound, the UnboundFetch event will be called to fetch the data to be displayed in the cell.

When UnboundFetch executes, the Data Control will usually not be at the row specified by the Row argument.  Hence you cannot reliably use the Recordset to retrieve database fields for the specified Row.  However, for the duration of the UnboundFetch event's execution, ColumnText will return the column text for the row specified by Row, rather than for the current row.


Grid Update Event

See Also	Example	Group

Syntax	Grid_Update(Row As Long, Col As Integer, Value As String)

Description	This event is sent whenever the user has changed the text in the specified cell and is about to commit the change by moving to a different cell.  If this event is sent, then the contents of the cell have already been validated.  Update is also called for calculated and unbound columns in database mode as well as callback mode.

This event is most useful in callback mode, where it is the only way changes to data in the grid can take effect.  Typically, callback mode users will use this event to store the grid data someplace where it can be accessed the next time a Fetch event is sent.

In database mode, all data storage is automatic.  However, actual record data is not updated by Visual Basic until the row position changes.  Thus, each cell update reflects that the user has changed the data and it is being held in the internal grid change buffer until it is written to the database.


Grid Validate Event

See Also	Example	Group

Syntax	Grid_Validate(Row As Long, Col As Integer, Value As String, Cancel As Integer)

Description	In both database and callback modes, this event is sent whenever the user has changed the text in the specified cell and is about to commit the change by moving to a different cell.  If this event is not used, all changes are valid.  If this event code executes without setting the value of the Cancel parameter, then the specified value is valid.  Validate is also called for calculated and unbound columns in database mode as well as callback mode.

Setting the Cancel parameter to True causes the grid to remain in editing mode until the data is valid.  If the Validate handler is triggered because the grid has lost focus, then setting Cancel to True will cause the grid to force focus to return to the editing area automatically.

The validation code can perform any steps necessary to validate the input data.  However, the code should avoid accessing or changing the current database (in database mode), or setting any properties which may affect the current cell position in the grid.

Note that actual record data is not written to the database until the current row position changes.  Thus, the Validate handler can be used to validate data immediately upon entry in the grid.  Additional validation may be necessary (or desirable) in the Data Control Validate handler, since it is called when the actual database update is about to occur.


Grid ValidateError Event

See Also	Group

Syntax	Grid_ValidateError()

Description	This event is generated when the user attempts to enter a non-valid entry into a column that is using value lists.  For this event to be activated the VlistStyle property needs to be set with GVLS_VALIDATE.  If the VlistStyle property is set to this value and the user types a value in that column that is not in the defined value list then this error will be generated.

This event is useful even if the user is able to enter values not in the Value list.  You may want to add that value to the list in this event.  It also allows you control how you want to repond to the incorrect input.


Grid Standard Events

Standard Events

The grid also supports the following standard Visual Basic events.  Consult the Visual Basic documentation for details.

Click	DblClick	DragDrop	DragOver

GotFocus	KeyDown	KeyPress	KeyUp

LostFocus	MouseDown	MouseMove	MouseUp


Visual Basic Format Strings

TrueGrid uses standard Visual Basic format strings to provide display editing for columns within the Agility grid control.  In Visual Basic, the Format$ function is used to edit values.  These format strings may be entered at design time using the layout editor "Edit Mask..." option or by using the EditMask property.  The following paragraphs describe the Visual Basic format string capabilities.

To format numbers, you can use the commonly-used formats that have been predefined in Visual Basic or you can create user-defined formats with standard characters that have special meaning when used in a format expression.

The following table shows the predefined numeric format names you can use and the meaning of each:

Format name	Description

General Number	Display the number as is, with no thousand separators.

Currency	Display number with thousand separator, if appropriate; display negative numbers enclosed in parentheses; display two digits to the right of the decimal separator.

Fixed	Display at least one digit to the left and two digits to the right of the decimal separator.

Standard	Display number with thousand separator, if appropriate; display two digits to the right of the decimal separator.

Percent	Display number multiplied by 100 with a percent sign (%) appended to the right; display two digits to the right of the decimal separator.

Scientific	Use standard scientific notation.

Yes/No	Display No if number is 0, otherwise display Yes.

True/False	Display False if number is 0, otherwise display True.

On/Off	Display Off if number is 0, otherwise display On.

The following table shows the characters you can use to create user-defined number formats and the meaning of each:

Character	Meaning

Null string	Display the number with no formatting.

0	Digit placeholder.

Display a digit or a zero.  If there is a digit in the expression being formatted in the position where the 0 appears in the format string, display it; otherwise, display a zero in that position.

If the number being formatted has fewer digits than there are zeros (on either side of the decimal) in the format expression, leading or trailing zeros are displayed.  If the number has more digits to the right of the decimal separator than there are zeros to the right of the decimal separator in the format expression, the number is rounded to as many decimal places as there are zeros.  If the number has more digits to the left of the decimal separator than there are zeros to the left of the decimal separator in the format expression, the extra digits are displayed without modification.

#	Digit placeholder.

Display a digit or nothing.  If there is a digit in the expression being formatted in the position where the # appears in the format string, display it; otherwise, display nothing in that position.

This symbol works like the 0 digit placeholder, except that leading and trailing zeros aren't displayed if the number has the same or fewer digits than there are # characters on either side of the decimal separator in the format expression.

.	Decimal placeholder.

The decimal placeholder determines how many digits are displayed to the left and right of the decimal separator.  If the format expression contains only number signs to the left of this symbol, numbers smaller than 1 begin with a decimal separator.  If you want a leading zero to always be displayed with fractional numbers, use 0 as the first digit placeholder to the left of the decimal separator instead.  The actual character used as a decimal placeholder in the formatted output depends on the Number Format specified in the International section of the Microsoft Windows Control Panel.  For some countries, a comma is used as the decimal separator.

%	Percentage placeholder.

The expression is multiplied by 100.  The percent character (%) is inserted in the position where it appears in the format string.

,	Thousand separator.

The thousand separator separates thousands from hundreds within a number that has four or more places to the left of the decimal separator.  Standard use of the thousand separator is specified if the format contains a comma surrounded by digit placeholders (0 or #).  Two adjacent commas or a comma immediately to the left of the decimal separator (whether or not a decimal is specified) means "scale the number by dividing it by 1000, rounding as needed."  You can scale large numbers using this technique.  For example, you can use the format string "##0,," to represent 100 million as 100.  Numbers smaller than 1 million are displayed as 0.  Two adjacent commas in any position other than immediately to the left of the decimal separator are treated simply as specifying the use of a thousand separator.  The actual character used as the thousand separator in the formatted output depends on the Number Format specified in the International section of the Control Panel.  For some countries, a period is used as the thousand separator.

E- E+ e- e+	Scientific format.

If the format expression contains at least one digit placeholder (0 or #) to the right of E-, E+, e-, or e+, the number is displayed in scientific format and E or e is inserted between the number and its exponent.  The number of digit placeholders to the right determines the number of digits in the exponent.  Use E- or e- to place a minus sign next to negative exponents.  Use E+ or e+ to place a minus sign next to negative exponents and a plus sign next to positive exponents.

:	Time separator.

The time separator separates hours, minutes, and seconds when time values are formatted.  The actual character used as the time separator depends on the Time Format specified in the International section of the Control Panel.

/	Date separator.

The date separator separates the day, month, and year when date values are formatted.  The actual character used as the date separator in the formatted output depends on Date Format specified in the International section of the Control Panel.

- + $ ( ) space	Display a literal character.

To display a character other than one of those listed, precede it with a backslash (\) or enclose it in double quotation marks (" ").

\	Display the next character in the format string.

Many characters in the format expression have a special meaning and can't be displayed as literal characters unless they are preceded by a backslash.  The backslash itself isn't displayed.  Using a backslash is the same as enclosing the next character in double quotation marks.  To display a backslash, use two backslashes (\\).

Examples of characters that can't be displayed as literal characters are the date- and time-formatting characters (a, c, d, h, m, n, p, q, s, t, w, y, and /:), the numeric-formatting characters (#, 0, %, E, e, comma, and period), and the string-formatting characters (@, &, <, >, and !)."ABC"	Display the string inside the double quotation marks.

To include a string in fmt from within Visual Basic, you must use Chr(34) to enclose the text (34 is the ANSI code for a double quotation mark).

*	Display the next character as the fill character.

Any empty space in a field is filled with the character following the asterisk.  Unless the fmt argument contains one of the predefined formats, a format expression for numbers can have from one to four sections separated by semicolons.

If you use	The result is

One section only	The format expression applies to all values.

Two sections	The first section applies to positive values and zeros, the second to negative values.

Three sections	The first section applies to positive values, the second to negative values, and the third to zeros.

Four sections	The first section applies to positive values, the second to negative values, the third to zeros, and the fourth to Null values.

The following example has two sections: the first defines the format for positive values and zeros; the second section defines the format for negative values.

"$#,##0;($#,##0)"

If you include semicolons with nothing between them, the missing section is printed using the format of the positive value.  For example, the following format displays positive and negative values using the format in the first section and displays "Zero" if the value is zero.

"$#,##0;;\Z\e\r\o"

Some sample format expressions for numbers are shown below. (These examples all assume that Country is set to United States in the International section of the Control Panel.)  The first column contains the format strings.  The other columns contain the output that results if the formatted data has the value given in the column headings.

Format (fmt)	Positive 5	Negative 5	Decimal .5	Null

Null string	5	-5	0.5

0	5	-5	1

0.00	5.00	-5.00	0.50

#,##0	5	-5	1

#,##0.00;;;Nil	5.00	-5.00	0.50	Nil

$#,##0;($#,##0)	$5	($5)	$1

$#,##0.00;($#,##0.00)	$5.00	($5.00)	$0.50

0%	500%	-500%	50%

0.00%	500.00%	-500.00%	50.00%

0.00E+00	5.00E+00	-5.00E+00	5.00E-01

0.00E-00	5.00E00	-5.00E00	5.00E-01

Numbers can also be used to represent date and time information.  You can format date and time serial numbers using date and time formats or number formats because date/time serial numbers are stored as floating-point values.

To format dates and times, you can use either the commonly used formats that have been predefined in Visual Basic or create user-defined time formats using standard characters that have special meaning when used in a format expression.

The following table shows the predefined data format names you can use and the meaning of each:

Format Name	Description

General Date	Display a date and/or time.  For real numbers, display a date and time. (e.g. 4/3/93 05:34 PM); If there is no fractional part, display only a date (e.g. 4/3/93); if there is no integer part, display time only (e.g. 05:34 PM).

Long Date	Display a Long Date, as defined in the International section of the Control Panel.

Medium Date	Display a date in the same form as the Short Date, as defined in the International section of the Control Panel, except spell out the month abbreviation.

Short Date	Display a Short Date, as defined in the International section of the Control Panel.

Long Time	Display a Long Time, as defined in the International section of the Control Panel. Long Time includes hours, minutes, seconds.

Medium Time	Display time in 12-hour format using hours and minutes and the AM/PM designator.

Short Time	Display a time using the 24-hour format (e.g. 17:45)

The following table shows the characters you can use to create user-defined date/time formats and the meaning of each:

Character	Meaning

c	Display the date as ddddd and display the time as t t t t t, in that order.  Only date information is displayed if there is no fractional part to the date serial number; only time information is displayed if there is no integer portion.

d	Display the day as a number without a leading zero (1-31).

dd	Display the day as a number with a leading zero (01-31).

ddd	Display the day as an abbreviation (Sun-Sat).

dddd	Display the day as a full name (Sunday-Saturday).

ddddd	Display a date serial number as a complete date (including day, month, and year) formatted according to the Short Date setting in the International section of the Windows Control Panel.  The default Short Date format is m/d/yy.

dddddd	Display a date serial number as a complete date (including day, month, and year) formatted according to the Long Date setting in the International section of the Control Panel.  The default Long Date  format is mmmm dd, yyyy.

w	Display the day of the week as a number (1 for Sunday through 7 for Saturday.)

ww	Display the week of the year as a number (1-53).

m	Display the month as a number without a leading zero (1-12).  If m immediately follows h or hh, the minute rather than the month is displayed.

mm	Display the month as a number with a leading zero (01-12).  If m immediately follows h or hh, the minute rather than the month is displayed.

mmm	Display the month as an abbreviation (Jan-Dec).

mmmm	Display the month as a full month name (January-December).

q	Display the quarter of the year as a number (1-4).

y	Display the day of the year as a number (1-366).

yy	Display the year as a two-digit number (00-99).

yyyy	Display the year as a four-digit number (100-9999).

h	Display the hour as a number without leading zeros (0-23).

hh	Display the hour as a number with leading zeros (00-23).

n	Display the minute as a number without leading zeros (0-59).

nn	Display the minute as a number with leading zeros (00-59).

s	Display the second as a number without leading zeros (0-59).

ss	Display the second as a number with leading zeros (00-59).

t t t t t	Display a time serial number as a complete time (including hour, minute, and second) formatted using the time separator defined by theTime Format in the International section of the Control Panel.  A leading zero is displayed if the Leading Zero option is selected and the time is before 10:00 A.M. or P.M.  The default time format is h:mm:ss.

AM/PM	Use the 12-hour clock and display an uppercase AM with any hour before noon; display an uppercase PM with any hour between noon and 11:59 PM.

am/pm	Use the 12-hour clock and display a lowercase AM with any hour before noon; display a lowercase PM with any hour between noon and 11:59 PM.

A/P	Use the 12-hour clock and display an uppercase A with any hour before noon; display an uppercase P with any hour between noon and 11:59 PM.

a/p	Use the 12-hour clock and display a lowercase A with any hour before noon; display a lowercase P with any hour between noon and 11:59 PM.

AMPM	Use the 12-hour clock and display the contents of the 1159 string (s1159) in the WIN.INI file with any hour before noon; display the contents of the 2359 string (s2359) with any hour between noon and 11:59 PM.  AMPM can be either uppercase or lowercase, but the case of the string displayed matches the string as it exists in the WIN.INI file.  The default format is AM/PM.

The following are examples of user-defined date and time formats:

Format	Display

m/d/yy	12/7/58

d-mmmm-yy	7-December-58

d-mmmm	7 December

mmmm-yy	December 58

hh:mm AM/PM	08:50 PM

h:mm:ss a/p	8:50:35 p

h:mm	20:50

h:mm:ss	20:50:35

m/d/yy h:mm	12/7/58 20:50

Strings can also be formatted with Format[$].  A format expression for strings can have one section or two sections separated by a semicolon.

If you use	The result is

One section only	The format applies to all string data.

Two sections	The first section applies to string data, the second to Null values and zero-length strings.

You can use any of the following characters to create a format expression for strings:

Character	Meaning

@	Character placeholder.

Display a character or a space.  If there is a character in the string being formatted in the position where the @ appears in the format string, display it; otherwise, display a space in that position.  Placeholders are filled from right to left unless there is an ! character in the format string.  See below.

&	Character placeholder.

Display a character or nothing.  If there is a character in the string being formatted in the position where the & appears, display it; otherwise, display nothing.  Placeholders are filled from right to left unless there is an ! character in the format string.  See below.

<	Force lowercase.

All characters are displayed in lowercase format.

>	Force uppercase.

All characters are displayed in uppercase format.

!	Force placeholders to fill from left to right instead of right to left.


 Summary of Recent Changes

This section summarizes recent changes made to TrueGrid and the TrueGrid on-line documentation.  Change history is by version number, with the most recent changes first.

Important: The value list and column summary features, described in Version 2.1, are fully documented in the on-line help file.  They are also present in the addendum at the back of the TrueGrid Pro printed manual.

Version 2.1c	6-May-94

1.	Apex has added a BBS!!!  You can reach us at 412-681-4370.  We will be posting all the latest patches and any new samples that become available on it.  It is a standard setup (8 data bits, 1 stop bit, Parity None), simply type BBS at the first login prompt then follow the instructions.

2.	The Querymark and Markchange events are now available for non-bookmarkable databases.  In prior versions, non-bookmarkable sets (such as SQLPASSTHRU dynasets) could not use the row selection features, even if you wanted to perform row marking yourself via QueryMark and MarkChange.  This version allows the use of QueryMark and MarkChange when a database is non-bookmarkable.  When a database is bookmarkable, you must use the BookmarkList and BookmarkCount properties to control the selection set.

3.	Column word wrapping can now be disabled.  There is a new property, ColumnWordWrap, which allows you to turn word wrap on or off for a column:

Table1.ColumnWordWrap(1) = False

There is also a new checkbox in the Column Properties Dialog which allows you to set this flag at design-time.

4.	Shorthand for ColumnText function in calculated expressions.  The Ct() function can now be used as a synonym for the ColumnText() function when used within a calculated expression.  Calculated expressions are set in the Column Properties Dialog, and using the ColumnExpression property.  ColumnText, because of the length of its name, could sometimes limit the size of an expression.

5.	Added the LayoutChange event.  The LayoutChange event is fired to indicate that (a) the user has made interactive changes to splits or columns, (b) a fresh layout has been automatically read from the database, and (c) the Layout or LayoutIndex properties have been set.

6.	International Numeric Support.  If the international currency settings are modified in the Control Panel, TrueGrid now properly accepts and displays international numbers in the desired format.  In addition, two functions (CDbl and CCur) have been added to the calculated expression parser.  These functions operate just like Val(), except they recognize internationally formatted numbers (Val always uses U.S. format).

7.	The Append event is now fired when you attempt to scroll past the last row using the mouse.  It is fired only once or until the user enters data in the new row.

8.	ComboSelect event added.  When using a built-in value list combo, ComboSelect will be fired whenever the user has selected (by clicking) one of the combo items, but has not yet left cell editing mode.

9.	Properties pop-up shortcut.  In TrueGrid Pro, when in the layout editor, double clicking on a column now takes you directly into the Column Properties Dialog instead of popping up the pop-up menu.  The right mouse button still pops up the pop-up menu as it did before.

10.	GotFocus is now properly fired when editing begins.  If TrueGrid didn't have focus, and editing commenced by setting EditActive to True, or by clicking on the combo button, TrueGrid would previously not receive the GotFocus event.

11.	Large numbers of columns cause display problems.  Using a large number of columns could sometimes cause the background to appear all grey.

12.	Large numbers of columns caused GPFs.  Using more than 700 columns would cause a GPF.  Now, you can use up to 1024 columns without difficulty.  Attempting to create more than 1024 columns will cause an error "Column limit exceeded".

13.	ColumnComboMaxItems error.  The ColumnComboMaxItems property would always return "Invalid Property Value" when you tried to set it.  Fixed.

14.	Summary calculations could cause incorrect row data.  In rare circumstances, the presence of column summaries could cause incorrect display of some row data when using AddNew.

15.	Display errors when using splits.  In rare circumstances, a split could display its background improperly if special colors or fonts were used in an adjacent split.  Fixed.

16.	Deleting last row left a blank row.  When deleting the last row in a set of records, TrueGrid previously left a blank row in the grid, although accessing the row could cause an error.  This has been fixed.

17.	EnterEdit fired incorrectly.  When a column was not editable, EnterEdit was still fired when an attempt was made to edit the cell.  This also fixes some problems with column summaries whenever non-editable cells were present.

18.	Change now fired upon first keystroke.  When editing was started using a keystroke instead of the mouse, the Change event was not fired for the first keystroke.

19.	Unexpected exit from VB.  TrueGrid could annoyingly (and randomly) exit from VB in rare cases where the Layout property was set.  This has been fixed.

20.	SQLPASSTHRU databases could cause "No Current Record."  When using non-bookmarkable databases, such as SQLPASSTHRU databases, TrueGrid was managing the record set clumsily and could cause errors such as "No Current Record".  This has been fixed.

21.	Contrary to the documentation, version 2.1a ignored assignments to the Text property rather than putting the current cell into edit mode.

22.	Date/time incorrect with edit masks.  Rounding errors could occur with date/time fields, causing the time to be displayed incorrectly.  This error only occured when the time was displayed in a Date/Time field that was editmasked.

23.	Repeated Append events are now suppressed.  In prior versions, Append would be triggered always, regardless of whether an AddNew was in progress.  Now, Append will not be triggered if (a) AddNew is in progress AND (b) no data has been modified in the current row.

Version 2.1a	28-Jan-94

1.	Fixed problems relating to how TrueGrid allocates GDI resources.  Most notable when using the more complex configurations of the grid.  Would sometimes produce a VB Out of Memory message.  Could also permanently delete GDI resources.  This has all been fixed and in some cases even made more efficient.  Grid performance could be 2 to 3 times faster.

2.	3D lines now work on displays with >32K colors.

3.	If the DataMode property was set to Callback mode and the DataSource property was set you may see some database behavior exhibited.  This problem has been fixed.

4.	Fixed GPF when refreshing column 0 (the current column).

5.	Fixed bug which causes dates to be improperly formatted if there is a foreign language setting and you are using a format mask.

6.	Problems with assiging to the ColumnSum Propertynot firing a ColumnSumChange event have been fixed.

7.	Fixed problem with SelText returning the wrong text string and possibly resulting in a GPF.

8.	Changing text in the edit portion of a combo, within the Column Properties Dialog, would not result in an update mode being set

9.	Fixed several problems with the SelectZoneWidth property and splits.

10.	TrueGrid now supports NT!!!

Version 2.1	20-Dec-93

1.	TrueGrid now supports value lists.  A value list allows you to define a set of values which can appear in a column.  These values can be used for a variety of purposes, and can even be used to associated pictures with specific cell values.  The value list features are comprehensive and include both design-time dialogs as well as a complete set of properties for manipulating value lists in your code.  See the section under How to on using value list features, Introduction to value list.

2.	TrueGrid will display bitmaps in cells using either value lists, or  by assigning to  the Picture property.

3.	You can now have TrueGrid automatically keep track of the total for a column.  When ColumnSumEnable is set to True for a column, TrueGrid will maintain the column total, tracking updates automatically.  The ColumnSumChange event is fired whenever TrueGrid senses a change in the column sum.  It is up to you to decide what to do with the toal itself.

4.	When using column format strings (with EditMask or the Column Properties Dialog),  TrueGrid now applies the mask in both callback mode and database mode.  Previous versions did not support edit masks in callback mode.

5.	When the "auto-validate" feature is used in value lists, TrueGrid now fires the ValidateError event if the user types a value which is not in the list.   TrueGrid will keep the user's focus in the incorrect cell after this event is fired.  (This property is not present in the manual or elsewhere in the on-line help.)

6.	It is now possible to customize the size of the "checkmark zone" used by TrueGrid to select rows whenever SelectMode enables this feature..  The property SelectZoneWidth can be used to set the size, in pixels, of the select zone area.  (The SelectZoneWidth property is not present in the manual or elsewhere in the on-line help.)

7.	In prior versions of TrueGrid Pro, calculated numeric columns would include a leading space before positive numbers (just like the STR$ function).   This space is now omitted and calculated columns look just like other numeric columns with respect to output. NOTE: If you have been using value lists with calculated numeric columns, this release may not match the values you have specified in previous versions.  This is true only if you are using value lists on columns which are calculated and which are numeric.

8.	Visual Basic operators MOD, NOT, AND, OR, XOR, EQV, and IMP would be recognized even if there was no space following them.  Thus, a variable name "NOTES" used in a calculated expression would be interpreted as "NOT ES".  This has been fixed.

9.	A new property, LayoutIndex, allows the use of multiple layouts, either at design-time or runtime.  By default, LayoutIndex is set to 1 (the default layout number).  Setting this number to 2, for example, will choose another "layout slot".  Any changes you make to the layout in the layout editor will be part of layout #2.  Changing LayoutIndex to 1 reselects the original ayout.  At design time, this makes the new layout (and associated properties) appear.  At runtime, the behavior is similar and can be used to switch between a variety of pre-designed layouts for the same grid..  (This property is not present in the manual or elsewhere in the on-line help.)

This feature is useful if a grid is used to display data from several different databases.  For example, you could lay out the grid for one database as layout #1.  Then, choose another RecordSource in the associated data control and change LayoutIndex to 2.  This doesn't cause the layout to change, but rather uses the existing layout as a starting point.  If you want to start from scratch, bring up the layout editor, choose "Clear Fields", the "Close".  Layout #2 is now "empty".  If you bring up the layout editor, you can now get the default field list for the new RecordSource and customize from there.  At runtime, you can change LayoutIndex to correspond to the RecordSource you are currently using.

Changing LayoutIndex also affects the layout referred to when you access the Layout property, or set it to a new value.

You can define up to 100 layouts, but beware that each layout takes up memory, so don't use them with wild abandon.  A typical multi-column layout takes several hundred bytes.  But, if you include value lists in your layouts (especially if bitmaps are used), the layout space can increase dramatically.


Property and Event Reference by Area

  Overall grid color

  Colors specific to splits

  Colors specific to columns within splits

  Overall grid fonts

  Fonts specific to splits

  Fonts specific to columns within splits

  Per-cell colors and fonts

  Controlling margins within cells

  Heading size and presence

  Horizontal and vertical grid lines

  Miscellaneous grid appearance properties

  Row and column numbering

  Calculated, bound, and unbound columns

  Miscellaneous column information

  Scrollbars

  Layout configuration

  User keyboard and mouse navigation

  User modification of grid appearance

  Editing cell contents

  Controlling database behavior

  Working with multiple row selections

  Controlling splits

  Drag and drop

  Determining cell dimensions and location

  Finding cells based upon coordinates

  Programmer control

  Value list

  Column Summary


Group:  Overall grid color

These properties control the overall color of the grid.  They are the default colors used by all splits, and all columns of the grid.  These can be overridden by changing split-specific, column specific, and cell-specific colors.  These color values are not split-specific, but apply globally.

Properties

BackColor	Changes the background color of the grid to the specified color value.  Can be changed at design time or runtime.

ForeColor	Changes the foreground color of the grid to the specified color value.  Can be changed at design time or runtime.


Group:  Colors specific to splits

TrueGrid allows certain "basic" colors to be set to control default colors for the headings (whether active or inactive), marked rows, vertical and horizontal lines, and the color of a cell when it is in editing mode.  These properties can be set at design time or runtime.  If changed, they take effect immediately.

These properties are affected by the setting of SplitPropsGlobal.  If it is False, then the setting will apply only to the current split; if True it applies to all splits.

Properties

EditBackColor	Controls the background color of a cell when it is opened for editing.  By default, this property is set to the system highlight background color.  Because of this, text selected with the mouse (although still selected) will not be evident.  Change this property (and EditForeColor) if you want to differentiate highlighted text.

EditForeColor	Controls the foreground color of a cell when it is opened for editing.

HeadBackColor	Specifies the background color of the headings whenever the grid is active.  When inactive, the InactiveBackColor is used for the headings.  If there are multiple splits, this color is used only for the current split.

HeadForeColor	Specifies the foreground color of the headings whenever the grid is active.  When inactive, the InactiveForeColor is used for the headings.  If there are multiple splits, this color is used only for the current split.

HorzColor	Specifies the color used for horizontal lines (if present).  If the HorzLines property is set to 3D mode, then this color specifies the color of the darker border of 3D bevels; the lighter color is derived from this.

InactiveBackColor	Controls the background color of the headings whenever the grid (or split) is inactive.

InactiveForeColor	Controls the foreground color of the headings whenever the grid (or split) is inactive.

SelectedBackColor	If a row is currently selected by marking the row, this color specifies the background color for that row.  By default, the color is black.  Selected rows are shown only if SelectMode is set accordingly.  This color can be overridden by cell-specific color settings.

SelectedForeColor	If a row is currently selected by marking the row, this color specifies the foreground color for that row.  By default, the color is black.  Selected rows are shown only if SelectMode is set accordingly.  This color can be overridden by cell-specific color settings.

VertColor	Specifies the color used for horizontal lines (if present).  If the HorzLines property is set to 3D mode, then this color specifies the color of the darker border of 3D bevels; the lighter color is derived from this.


Group:  Colors specific to columns within splits

Each column can have its own default background and foreground color, specified by these properties.  These properties can be set only at runtime and can be overridden by cell-specific color settings if desired.  These colors accept a special value, INHERIT_COLOR (defined in TGCONST.TXT) which indicates that the column color is to be inherited from the default grid color.

These properties are affected by the setting of SplitPropsGlobal.  If it is False, then the setting will affect the column only within the current split; if True it applies to the column in all splits.

Properties

ColumnBackColor	Specifies the background color of the column.  The default setting is INHERIT_COLOR, indicating that the column has no special background color.

ColumnForeColor	Specifies the foreground color of the column.  The default setting is INHERIT_COLOR, indicating that the column has no special foreground color.


Group:  Overall grid fonts

TrueGrid allows customization of fonts in a variety of circumstances.  However, the basic font face (specified by FontName) and the point size of the font (FontSize) are global to the entire grid and cannot be changed.

These properties are not affected by SplitPropsGlobal, and control the base font used for all cells and headings in the grid.

Properties

FontBold	If True then the base font will be bold.  This is the default.

FontItalic	If True then the base font will be italic.  Defaults to False.

FontName	Specifies the font typeface name to be used for all grid cells and headings.  This font cannot be overridden and must apply globally to the entire grid.  However, the bold, italic, and underline properties of the font (referred to as the font style) can be changed selectively on a per-column or per-cell basis, as well as for the headings.

FontSize	This property specifies the point size for fonts used within the entire grid and cannot be overriden.  The setting of this property determines the height of a line of text, and is the basis for the heading height and row height.

FontStrike	If True then the base font will use strike-out text.  This setting is global and cannot be overridden.  Defaults to False.

FontUnder	If True then the base font will be underlined.  This setting is global, and can be overridden on a column or per-cell basis.  Defaults to False.


Group:  Fonts specific to splits

The headings may use a different font style than the rest of the grid.  This property is affected by the setting of SplitPropsGlobal.  If it is False, then the property applies to the headings in the current split only; if True then all headings are affected.  This property is available at design-time and runtime.

Properties

HeadFontStyle	Specifies the font style to be used for headings.  Defaults to 0, meaning that the font style is inherited from the global grid font settings.


Group:  Fonts specific to columns within splits

The font style can be specified on a per-column basis and can be used to override the base font style.  These properties can be set at runtime, or at design-time in the layout editor.  These font styles accept a special value, INHERIT_FONT (defined in TGCONST.TXT) which indicates that the column font is to be inherited from the default grid font.

These properties are affected by the setting of SplitPropsGlobal.  If it is False, then the setting will affect the column only within the current split; if True it applies to the column in all splits.

Properties

ColumnHeadFontStyle	Specifies the font style to be used for a heading for the specified column.  Defaults to INHERIT_FONT.

ColumnFontStyle	Specifies the font style to be used for cell text within the specified column.  Defaults to INHERIT_FONT.


Group:  Per-cell colors and fonts

TrueGrid supports an advanced technique, tailored to database usage, which permits colors and fonts to be specified on a per-cell basis.  Rather than "apply" colors and fonts to specific cells, TrueGrid has methods for defining cell colors based upon a cell's status or contents.  This makes font and color selection much faster, since TrueGrid has a better knowledge of how fonts and colors are intended to be used.

A special method (using the FetchAttributes event) allows cell color and font to be specified using any desirable means.  All of these properties use the special values INHERIT_FONT and INHERIT_COLOR (defined in TGCONST.TXT) to specify that no color or font override is provided for a specific case.

The use of these properties is somewhat complex, but they provide great power and flexibility.

All of these properties are affected by the setting of SplitPropsGlobal.  If it is False, then the setting will affect the column only within the current split; if True it applies to the column in all splits.

Meaning of Cell Status Values

There are 16 separate cell status values, which indicate the disposition of a cell.  The status is a combination of four separate conditions:

1.	Current cell.  The cell is the current cell, specified by the ColumnIndex and RowIndex properties.

2.	Part of a highlighted row marquee.  When the MarqueeStyle property indicates that the entire row is to be highlighted, cells in such rows have this additional condition set.

3.	Updated data.  The data in the cell has been updated by user modification, or setting the Text or ColumnText properties.

4.	Marked row.  The cell is part of a row marked by the user (or programmer) and displayed as such according to the setting of the SelectMode property.

The cell status is a combination of these four conditions and there are a total of 16 different cell dispositions, shown in the following table:

Status	Condition of Cell				Meaning of
Value	Row Marked	Data Changed	Row Marquee	Current Cell	Status Value
0					Normal cell, not current, marked, changed, or part of a highlighted row.
1				X	The current cell, not marked, changed or part of a highlighted row.
2			X		Part of a highlighted row, not current, marked or changed.
3			X	X	Current cell in highlighted row, not marked or changed.
4		X			Changed cell, not current, marked, or part of a highlighed row
5		X		X	Current cell when changed, not marked or part of a highlighted row.
6		X	X		Cell changed within a highlighted row, not current or marked.
7		X	X	X	Current cell changed within a highlighted row, not marked.
8	X				Row within a marked cell, not current, changed, or part of a highlighted row.
9	X			X	Current cell within a marked row, not changed or part of a highlighted row.
10	X		X		Cell in a marked row which is also the highlighted row, not current cell and not changed.
11	X		X	X	Current cell in a marked row which is also the highlighted row, but not changed.
12	X	X			Cell within a marked row in which data has been changed, not current and not part of a highlighted row.
13	X	X		X	Current cell within a marked row in which data has been changed; not part of a highlighted row.
14	X	X	X		Cell within a marked row (which is also highlighted) in which data has been changed, but not the current cell.
15	X	X	X	X	Current cell within a marked row which is also highlighted.  Data in the cell has been changed.

Each status value is distinct, and you can set a different set of colors and fonts for each of the 16 status conditions.  That is, setting attributes for status 1 affects the current cell, but only when it is not marked, is not changed, and is not part of a highlighted row marquee.  To affect the current cell under all circumstances, you would need to set the attributes for status values 1, 3, 5, 7, 9, 11, 13, and 15.  Usually, this is not necessary since no application will have cells of all possible status values.  For example, if the marquee is set to a dotted cell, then none of the status values which indicate a row marquee condition will ever be encountered.

Parameter Properties

These properties do not actually change the grid appearance, but are used as parameters for other cell-specific color and font properties.  Usually, these properties must be set before using the cell-specific properties such as SetStatusAttr, ColumnSetStatusAttr, AddRegexAttr, and ColumnAddRegexAttr.

TrueGrid never modifies these properties, but initializes them all to a default value of INHERIT_COLOR or INHERIT_FONT.  The properties are available only at runtime, and are global to the entire grid (even though the attribute setting properties are specific to the current split).

ParamBackColor	Specifies the background color to be applied to the cells specified by subsequent setting of one of the per-cell attribute properties.  Defaults to INHERIT_COLOR.

ParamFontStyle	Specifies the font style to be applied to the cells specified by subsequent setting of one of the per-cell attribute properties.  Defaults to INHERIT_FONT.

ParamForeColor	Specifies the foreground color to be applied to cells specified by subsequent setting of one of the per-cell attribute properties.  Defaults to INHERIT_COLOR.

ParamStatus	Specifies the cell status of cells affected by regular expressions added with AddRegexAttr and ColumnAddRegexAttr.  There are 16 different cell status values.  This property defaults to the special value, -1, meaning that the regular expression applies to cells of any status.

Setting Per-Cell Attributes Based Upon Status

The following two properties allow you to apply the values of ParamForeColor, ParamBackColor, and ParamFontStyle to cells which have a given status.  These properties are available only at runtime and are write-only.

SetStatusAttr	Applies the attributes specified by ParamForeColor, ParamBackColor, and ParamFontStyle to all cells with a specified status.  The attributes are applied as cells are displayed, so once this property is set, the grid will respect the attributes as the grid is scrolled, or data is changed and refreshed.

ColumnSetStatusAttr	Like SetStatusAttr, but applies the attributes only to cells within a given column which have the specified status.  Overrides any settings provided with SetStatusAttr.

Setting Per-Cell Attributes Based Upon Cell Contents

TrueGrid allows you to specify attributes which are applied to a cell based upon whether the cell matches a particular regular expression.  A regular expression specifies a pattern which is tested against the cell contents whenever it is displayed or changed.  If the pattern matches, then the specified attributes are applied.  TrueGrid allows you to add an unlimited number of patterns with corresponding attributes.

AddRegexAttr	Adds a regular expression to the list of patterns for the current split (or all splits if SplitPropsGlobal is True).  ParamForeColor, ParamBackColor, and ParamFontStyle must be set before assigning to this propery.  The parameters specify the attributes which are applied when a pattern match occurs.  If ParamStatus is set to -1, then the pattern applies to all cells, regardless of status.  If ParamStatus contains a value from 0 to 16, then only cells of that status which match the pattern are affected.

ColumnAddRegexAttr	Like AddRegexAttr, but applies only to the specified column.  You may set patterns with both AddRegexAttr and ColumnAddRegexAttr.  Those set with ColumnAddRegexAttr take priority over those which are set with AddRegexAttr whenever a match occurs on both patterns.

ColumnHasRegexAttr	Returns True if the specified column has pattern attributes associated with it.  Setting it to False clears any pattern attributes for the column.

HasRegexAttr	Returns True if the current split has pattern attributes associated with it.  Setting this property to False clears any pattern attributes for the current split (or all splits if SplitPropsGlobal is True).

Setting Cell Colors and Fonts  Using User-Defined Criteria

For cases where status-dependent or pattern-dependent attribute settings are inappropriate, TrueGrid can query your program each time it needs to know cell attributes.  This is done via the FetchAttributes event.  The event will be triggered only for those columns which have the ColumnCellAttrs property set to True.  Using this capability, you can have cell colors and fonts which are dependent upon the contents of a cell (if it is a certain range, for example) or even dependent upon the contents of other cells and databases.

ColumnCellAttrs	If set to True for a column, then TrueGrid will trigger the FetchAttributes event each time it needs to know what the cell attributes will be.  TrueGrid optimizes this behavior so it calls FetchAttributes only when cells are scrolled into view, or when their contents or status changes.

FetchAttributes Event	This event is fired whenever TrueGrid needs to know the color and font to use for a cell within a column which has ColumnCellAttrs set to True.


Group:  Controlling margins within cells

TrueGrid allows you to change the left and right margin of each cell based upon any criteria you specify.  The cell margins are dynamic.  Each cell can have its own margins, and the margins can be changed as data changes.  This makes it possible to implement outlining features by indenting cells according to an outline level (usually stored in the database as well) or some other criteria.

Cell margins are specific to splits and can be enabled or disabled on a per-split basis.  SplitPropsGlobal is respected.  If SplitPropsGlobal is True, then turning on cell margins for a column affects all splits; otherwise, only the current split is affected.

Properties

ColumnFetchMargins	If True, then the specified column will have cell margins, which causes the FetchMargins event to be triggered each time the grid needs to know cell margins within the column.  Defaults to False for all columns.

Events

FetchMargins	If ColumnFetchMargins is True for a column, this event will be triggered each time the grid needs to know the cell margins (usually at the same time it fetches the cell data).  The cell margins are specified by the InsetLeft and InsetRight arguments, which are changed to reflect the new margins.  Margins are specified in 10ths of a character, so that the margins are proportional to the font being used.


Group:  Heading size and presence

TrueGrid allows you to have headings for columns, or to hide them.  These properties can be set at design time or runtime.  If changed, they take effect immediately.

Properties

Headings	If True then column headings are displayed; if False then there will be no column headings.  This property is affected by SplitPropsGlobal.  If it is True, then headings in all splits are affected; if False then only headings in the current split are affected.  If one split has headings and another does not, then the splits without headings show a "grey area" where the headings would be.

HeadingHeight	Specifies the height of the heading area, in lines.  This number can be fractional.  For example, 1.5 indicates that the headings should be 1.5 times as high as a single line of text.  Defaults to 1, and applies globally to all splits in the grid.


Group:  Horizontal and vertical grid lines

These properties specifiy how grid lines should appear.  Both properties support settings for no lines, single-width lines, and 3D lines.

Properties

HorzLines	Indicates whether horizontal grid lines appear.  This setting is global to the entire grid.  The setting of HorzColor specifies the color of the lines, and can be tailored to each split.

VertLines	Indicates whether vertical grid lines appear.  This setting is affected by SplitPropsGlobal.  If it is True, then the line setting applies to all splits; if False then only the current split is affected.


Group:  Miscellaneous grid appearance properties

Properties

MarqueeStyle	This property indicates how the marquee appears.  The marquee defaults to a dotted cell border.  Options include solid cell borders, highlighted cell, highlighted row, and highlighted row with a raised current cell.  You can also turn the marquee off using this property.  This property is affected by SplitPropsGlobal.  If it is True, then the marquee will be changed for all splits; if False, then only the current split is affected.

MarqueeUnique	If True, then there will be only one marquee, no matter how many splits are in the grid.  Changing splits will hide the marquee in one split and show it in the current split.  If False, then the marquee will be present in all splits.  The default is True.

BorderStyle	This property specifies whether the overall grid has a border or not.


Group:  Row and column numbering

These properties allow you to change and inspect the size of the grid (in rows and columns) as well as change the current cell pointer, left column, and top row values.  Events are included to determine when the cell pointer changes.

The current row number is global to the entire grid.  All splits within the grid will have the same current row number.  However, the column number can be different for each split.

Properties

BottomRow	Returns the number of the bottom row visible within the current split.  Splits are normally syncrhonzed, so this value will be the same for all splits.  However, if splits are unsynchronized (by changing their SplitGroup), the bottom row value may be different for each split.  This property is read-only and is available only at runtime.

ColumnIndex	Allows you to inspect or change the current column index.  Columns are numbered based upon their original order, even if the user rearranges them (ColumnOrder can be used to inspect the actual position on the display).  Setting this property is affected by SplitPropsGlobal.  If it is True, then changing this property changes the current column for all splits.

Columns	Returns the number of columns in the grid.  All splits must have the same number of columns, but columns can be hidden in some splits but not in others.  You can set this property to define the number of columns.  Setting it to zero removes all of the columns.

LeftColumn	Returns the column number of the leftmost column in the current split.  Setting this property will scroll the specified column so it is the leftmost.  If SplitPropsGlobal is True, then setting this property will change the leftmost column in all splits.

LinesPerRow	Specifies the number of lines which are displayed in each row of the grid.  This is an integer number (no fractions allowed) and applies globally to the entire grid.

ReferenceRow	Sets or returns the row number used for the ColumnText, CellRectLeft, CellRectTop, CellRectWidth, and CellRectHeight properties.  ReferenceRow is set automatically when a RowChange event occurs, or when the row number is temporarily different from RowIndex, such as in the UnboundFetch or FetchAttributes events.

RightColumn	Returns the column number of the rightmost column in the current split.  Read-only and available only at runtime.

RowIndex	Sets or returns the current row number for the grid.  The row number is global.  That is, all splits will have the same row index.

Rows	Returns the total number of rows in the grid.  In database mode, this number may not always reflect the actual size (if the number of rows is unknown).  You can set this property, but only in callback mode where the grid must know how many rows to display.

TopRow	Sets or returns the current top row number for the current split.  Normally, splits are synchronized, so setting the TopRow property will affect all splits even when SplitPropsGlobal is False.  However, if splits are unsynchronized (by setting SplitGroup), then the TopRow may be different for each split.

Events

CellChange	This event is triggered whenever a new cell becomes current.

ColumnChange	This event is triggered whenever a new column becomes current, or when the user moves to a different split which has a different current column than the current one.

LeftColChange	Triggered whenever the left column changes to a new value.  If there are splits, then this event is also triggered if a user changes splits and a new column becomes the left column (due to the difference in the horizontal position of the splits).

RowChange	This event is triggered whenever a new row becomes the current row.

TopRowChange	Triggered whenever the top row of the current split changes due to scrolling or because the value of TopRow has been changed in code.  If there are independent splits (with different SplitGroup numbers), then this event is also triggered when changing to another split which is scrolled to a different top row position in the database.


Group:  Calculated, bound and unbound columns
Group:  Calculated, bound, and unbound columns

When in database mode, TrueGrid columns can be bound, unbound, or calculated.  Bound columns are automatically fetched from the database based upon their ColumnField property and are automatically updated.  Unbound columns are filled in by the programmer using the UnboundFetch event.  Calculated columns include an expression (in ColumnExpression) which TrueGrid uses to automatically calculate the value of the column.  All column types receive the Validate and Update events whenever data is updated.  For unbound and calculated columns, updating may not be possible.  In such cases, the column should not be editable by the user (it is up to the programmer to configure this).

These properties apply globally to all columns in the grid.  In other words, a column cannot be bound in one split while being calculated in another.

Properties

ColumnExpression	Specifies the Visual Basic expression to be used for calculating the value of the column when the ColumnType indicates that the column is calculated.  Ignored for other column types, but still maintained.  The expression must be a valid expression.  Read/write at runtime.  At design time, can be set in the Layout editor.

ColumnField	Specifies the field name for a bound column when the ColumnType indicates that the column is a bound column.  Ignored for other column types, but still maintained.  Read/write at runtime.  At design time, can be set in the Layout editor.

ColumnType	Specifies whether the column is bound, unbound, or calculated.

Events

UnboundFetch	Triggered whenever an unbound column is scrolled into view and data is required.

Update	Triggered after a column has been updated by the user.

Validate	Triggered just before a column has been updated.  The proposed value for the new cell is provided, and can be changed if the data to be written is different (in format for example) from the data the user sees in the edited cell.


Group:  Miscellaneous column information

Each column has properties which define its behavior.  These properties define miscellaneous behavior.  Some are global, while others are specific to a particular split.

Properties

ColumnName	This property defines the string which will be used for the heading of a particular column.  This property is global to all splits; that is, the column must have the same heading in all splits.

ColumnOrder	The column numbers used in Visual Basic code remain constant as columns are moved.  This property defines the actual order of the column as it appears in the displayed grid.  The value can be changed to move the column from one position to another.  This property respects SplitPropsGlobal.  If it is True, then changing ColumnOrder will move the column to the same position in all splits.

ColumnStyle	This property defines the text justification, heading justification, and editability of a column.  Each split can have different values for the same column.  This property respects SplitPropsGlobal.  If True, changing ColumnStyle affects the column whereever it appears.

ColumnVisible	If True, the indicated column will be visible.  If False, the column will not be shown.  When the user resizes a column to zero width, this property is automatically set to False.  Columns may be hidden in one split while they remain visible in another.  If SplitPropsGlobal is True, setting this property changes the state of the column in all splits.

ColumnWidth	This property contains the width of the column, in characters.  Changing it will change the column width for the current split, or for all splits if SplitPropsGlobal is True.

ColumnWordWrap	Setting this property affect whether or not each column will wrap the last word on a line.  If set to True then that column will wrap the last word to the next line otherwise it will truncated the word and finish it on the next line.

EditMask	This property defines the Visual Basic Format$ string which will be used to format the text of the indicated column.  It defaults to an empty string (no formatting).  Changing this property will change the formatting of the column in all splits, regardless of the setting of SplitPropsGlobal.


Group:  Scrollbars

TrueGrid allows complete control over scrollbars.  These properties can specify whether horizontal or vertical scrollbars are never shown, always shown, or shown only if necessary.

These properties respect SplitPropsGlobal.  Setting these properties while SplitPropsGlobal is True affects the scrollbars in all splits, while setting them while SplitPropsGlobal is False affects the scrollbars of the current split only.

Properties

HorzScrollbar	Indicates whether horizontal scrollbars are shown, hidden, or displayed only when necessary.

VertScrollbar	Indicates whether vertical scrollbars are shown, hidden, or displayed only when necessary.


Group:  Layout configuration

The grid layout consists of a wide variety of split and column settings.  Settings can be customized at design time using the Layout editor, or saved and restored in their entirety at runtime using the Layout property.

Properties

Layout	At design time, clicking on this property brings up the layout editor, which allows customization of column settings and other grid configuration options.  At runtime, the Layout property contains a string which defines the complete layout of the grid, including splits, columns, column settings, etc.  You can save the contents of the Layout property in a string and restore it later by reassigning it to the Layout property.

The format of the string is internal, and is checked for validity upon assignment. The string may contain null characters, so it is best stored in a binary file.

LayoutIndex	You can use this property at design time to set up multiple layouts in the grid.  By changing the index number, the grid can be configured to a completely different layout.  At run time, by switching numbers it is possible to show different layouts.  You can also save changes the user makes to an existing layout.

Events

LayoutChange	This event notifies the programmer whenever the user makes changes to the layout.  This includes things like changing the column or split sizes, deleting or creating splits and major changes to the layout like change the database.  Using this property is possible to save the layout when the users makes these changes to the grid.


Group:  User keyboard and mouse navigation

Windows defines standard conventions for how the keyboard and mouse should operate.  By default, TrueGrid conforms to these conventions.  The tab key will move from cell to cell.  At the first or last cell, tabbing moves out of the grid to the next or previous control on a form.  Arrow keys maintain focus within the grid.

These properties are global to the entire grid and affect the way TrueGrid handles the arrows, tab key, and the mouse.

Properties

AllowArrows	If True (the default), then TrueGrid will respect the arrow keys for movement from cell to cell.  If False, then the Arrow keys will always have their default meaning (moving from control to control).

AllowTabs	If True (the default), then TrueGrid will respect the tab key for movement from cell to cell.  If False, then the tab key will always move between controls.

ExposeCellMode	Controls the behavior of the rightmost column when the user clicks on a cell in that column.  When set to 0 (the default) the grid will scroll to the left to make the cell visible so all of its text can be shown.  If set to 1 then the grid will not move, however if the user attempts to edit the cell then the grid will scroll left so you can see all of the cell text.  If ExposeCellMode is set to 2 then the grid will always leave the last cell clipped both when clicked and when the user attempts to edit the cell.

MousePointer	Defines the appearance of the mouse cursor when it is positioned over the grid.

SplitSelectable	If True, then the current split will be selectable by the user with the mouse, and the tab and arrow keys can be used to move into the split (providing SplitTabMode allows such behavior).  If False, then the user will not be able to select the split by clicking on it, and the split will be bypassed when moving from split to split with the keyboard.  Changing this property while SplitPropsGlobal is True will affect all splits, otherwise only the current split will be affected.

SplitTabMode	When set to 0 (the default), the tab and arrow keys will not cross split boundaries.  When set to 1, the tab and arrow keys will move to adjacent splits rather than be confined to the current split.  This property is global to the grid an is not affected by SplitPropsGlobal.

TabCapture	If False, then the tab key will exit the grid and move to another control if an attempt is made to tab past the last column or before the first.  If True, then the tab key will never exit the grid once it has focus.  The default for this property is False.

TabIndex	Specifies where the grid lies in the tab order of the current form.

TabStop	If True, then the tab key will stop at the grid.  If False, the tab key will bypass the grid and move to the next control in the tab sequence.

WrapCellPointer	If True, then the cell pointer will wrap from the last column to the first in the next row (or the first column to the last in the previous row).  This will always operate with the arrow keys if AllowArrows is True.  It will work with the tab key only if TabCapture is set to False, meaning that the tab key will not exit the grid.  If SplitTabMode is set to 0, the cell pointer will wrap only within the current split.  If SplitTabMode is set to 1, then the cell pointer will move from one split to the next before wrapping occurs.

Events

Click	Triggered whenever the user clicks on a cell within the grid.

DblClick	Triggered whenever the user double clicks on a cell within the grid.


Group:  User modification of grid appearance

By default, the user can change the column order, size, and can create new splits and resize them.  These properties control the users ability to do so.

Both properties respect SplitPropsGlobal.  Setting these properties while SplitPropsGlobal is True affects the configurability of all splits, otherwise only the current split is affected.

Properties

Configurable	If True, then the user may resize columns, rearrange them, and hide them.  If False, the column positions is fixed.  In addition, when this property is False, it is possible to detect a click within the heading area (normally, the heading area is used to rearrange columns).

SplitLocked	If True, then the current split may be resized.  If False, the current split cannot be changed.  If all splits are locked, then the user will be unable to create any new splits interactively.


Group:  Editing cell contents

TrueGrid automates the process of editing cell data.  Cells are either in display mode or edit mode, depending upon whether the user has begun typing in a cell or whether the cell has been selected with the mouse.  If the text is larger than the cell, TrueGrid will "drop-down" an editing box for editing the cell.  In this mode, the arrow keys are redefined to move within the drop-down editing area.

Properties

ColumnChanged	This property is read-only and available only at runtime.  If True, then the data in the specified cell has been updated by the user or through code modification.  If False, then the cell contains the original data.

ColumnSize	This property restricts user input to a specified number of characters.  If set to zero, then no limit is imposed.  This property is global to all splits.  That is, changing the value affects the data entry limit for the column wherever it appears.  At design time, this property can be changed in the layout editor.

ColumnText	This property contains the textual value of the specified column.  The value of this property will contain the unedited contents of the cell (without the EditMask applied).  Changing this value will cause the cell contents to be changed as if the user had modified the cell directly.  Since a cell contains the same value regardless of which split it appears in, this property does not respect the SplitPropsGlobal setting.

Normally, ColumnText refers to data within the current row.  However, when used within the FetchAttributes, UnboundFetch, or FetchMargins events, this property will reflect the value of the row being fetched, regardless of whether it is the current row or not.  When used in the context of these events, the ColumnText property cannot be changed (any change to the property is ignored).

Editable	If True, then the grid is editable.  If False, then edits are not allowed.  This property is global to the entire grid.

EditActive	If this property returns True, then the current cell is currently being edited by the user.  If False, then no editing is in progress.  Setting this property to True will cause editing to begin on the current cell (if it is not already in edit mode).  Setting it to False will exit edit mode.  If the cell has been modified, this causes the Validate and Update events to be set.  If you want to cancel editing, set the Modified property to False and then set EditActive to False.

EditDropDown	If True (the default) then the grid will automatically drop-down an editing box to allow editing of text which won't fit in the current cell.  If False, then editing is always constrained to the current cell boundaries.

Modified	This property is useful only while the current cell is opened for editing.  In such cases, Modified returns True the user has changed the data in the current cell and False if the data has been unchanged.  The value of this property can be changed at runtime to change the modified status of the editing cell.

SelLength	Allows you to set or inspect the length of the currently selected text within the editing cell.

SelStart	Returns the start position of the selection in the editing cell.  If SelLength is zero, returns the position of the caret.

SelText	Contains the selected text within the current cell being edited.  Can be set to overwrite the selected text.

SplitEditable	If True, then the current split may be edited.  If False, then editing is disallowed within the current split.  If SplitPropsGlobal is True, then setting this property affects the editability of all splits, otherwise only the current split is affected.  If the Editable property is False, then this property is ignored, but still maintained.

Text	Contains the text value of the cell being edited, otherwise returns an empty string.  Setting this property will change the contents of the current cell editing area and cause the grid to enter edit mode if it is not already editing the current cell.  Changing this property does not cause the RequestEdit event to be triggered.

Events

Change	This event is triggered each time the user makes a change to the current cell being edited.  The event is triggered for each character typed, just as for standard Visual Basic text boxes.

EnterEdit	This event is triggered once the current cell has been opened for editing.  In other words, the EditActive property will always be True when this event executes.  Although editing can be cancelled by setting EditActive to False in this event, the recommended method is to use the RequestEdit event.

ExitEdit	This event is triggered after the current cell has completed the editing process.  If editing is cancelled (because the user presses escape, or because EditActive is set to False on an unmodified cell), the event is not triggered.

RequestEdit	Whenever the user attempts to edit the current cell, this event is triggered.  The Cancel parameter can be set to True to cause the edit request to be ignored.  Editing can begin either by clicking with the mouse, or by typing into a cell.  The KeyAscii parameter to this event will be zero if the mouse was used to begin editing, or will contain the ASCII keycode used to begin the editing process.

Update	This event is sent after the current cell has successfully been edited.

Validate	This event is sent when the user completes editing of the current cell.  The validate event may cancel the update, or may change the updated value before it is written.


Group:  Controlling database behavior

TrueGrid generally handles all database operation smoothly and automatically.  The following properties are used to control the interface between Visual Basic and the bound TrueGrid control.

Properties

Active	If set to True, then TrueGrid respects all operations performed on the database using the Data Control or its Recordset.  If False, then TrueGrid ignores any database movement or updates performed in Visual Basic code or in conjunction with other bound controls.  However, even when False, TrueGrid will still fetch data from the database during scrolling or refresh operations.

DataChanged	This standard Visual Basic property will be True whenever data in the grid has been changed but not yet updated to the database.  Setting it to False will discard any pending changes in the grid.

DataSource	This property, available only at design-time, specifies the data control to which the grid is bound.

DataSourceHwnd	A runtime, this property may be set to the HWND of a Data Control to bind TrueGrid to that control dynamically.  It is possible to bind TrueGrid to a data control on another form using this property.  This property cannot be assigned to if DataSource has been set to a valid Data Control at design-time.

FetchMode	Normally, TrueGrid fetches cell data one cell at a time.  In some circumstances (such as with SQL servers), this mode may appear slow to the user, since each access will require more time.  This property allows you to change the method TrueGrid uses to fetch data to specify per-row or per-grid fetching rather than per-cell fetching which is the default.

Events

Append	When the user is positioned to the last row of the grid, pressing the down arrow key will trigger this event.  It is up to the programmer to perform an AddNew and Update to the database, which will be reflected in the grid.


Group:  Working with multiple row selections

TrueGrid supports marking of multiple rows in the grid.  This capability is enabled by setting the SelectMode property and examining the list of Bookmarks maintained by the grid.  Bookmarks can also be added to the Bookmark list to cause records to be marked.

Properties

BookmarkCount	Contains the number of rows currently selected, or the size of the BookmarkList.  Setting this property to zero clears all marked rows.  It cannot be set to any other value.

BookmarkList	This is a property array which contains a list of selected rows, identified by their bookmarks.  Setting an item to an empty string unmarks the row and removes the bookmark from the list.  You can add a bookmark by assigning a new bookmark to the item one past the end of the BookmarkList.

SelectMode	This property indicates whether selection is enabled, and whether the selected rows are visible.  Each may be controlled independently.  Although bookmarks are global to the grid, this property respects the SplitPropsGlobal setting.  Setting SelectMode while SplitPropsGlobal is True will change the selection mode for all splits in the grid; otherwise, only the current split is affected.

SelectZoneWidth	You can use this property to set the width of the area that allows the user to interactively select multiple rows.  The number represents the number of pixels from the left that the checkmark will appear in.  Note that in this zone the users will be unable to change rows.

Events

MarkChange	This event is triggered whenever the user marks or unmarks a row by clicking in the left margin of the grid.

QueryMark	This event operates only in callback mode.  It is triggered whenever the grid needs to know whether a row is currently selected.  It is up to the programmer to keep track of the list of selected rows, while TrueGrid handles the display and selection process.


Group:  Controlling splits

TrueGrid supports powerful multiple-split capabilities, which can be used for Excel-like user-controlled splits, or can be used to implement locked columns.  Although all splits display the same data, most properties are specific to a split and can be set differently for each split.  SplitPropsGlobal affects this behavior.

Properties

InsertSplit	Assigning an integer to this property will insert a new split before the split indicated by the integer value.

RemoveSplit	Assigning an integer to this property will remove the split indicated by the integer value.

SplitGroup	This property contains the group number for a split.  All splits with the same group number are "synchronized" so that they scroll simultaneously.  Changing the group number for a split will "unlink" it from other splits so that it may scroll independently in the vertical direction.  Splits are always independent for horizontal scrolling.

SplitIndex	This property contains the number of the current split, and can be changed to make a different split active.  Splits are numbered from 1 to the number of splits in the grid.  At design time, changing this property while SplitPropsGlobal is False allows you to set properties for a specific split within the design-time layout.

SplitPropsGlobal	This property affects the behavior of a large number of TrueGrid properties.  If True (the default), then all properties apply globally to all splits.  If False, then selected properties are applied only to the split identified by SplitIndex (the current split).  Most properties, including column properties, can be customized on a per-split basis.

Splits	Contains the number of splits currently present in the grid.  Setting this property to one higher than its current setting creates a new split.

SplitSize	This property contains the width of the split.  Its meaning is dependent upon the value of SplitSizeMode.  It contains either (a) a scale factor for the split, (b) the number of columns the split must contain, or (c) the width of the split in twips.

SplitSizeMode	This property determines how TrueGrid decides upon the size of the split.  It can be set to (a) size the split according to a scale factor, (b) force the split to always display an integral number of columns, or (c) size the split to a specified number of twips.

Events

SplitChange	This event is triggered whenever the SplitIndex is changed either by user interaction, or by changing the SplitIndex property directly in code.  The event is fired only once if SplitIndex is changed in code.


Group:  Drag and drop

Most of these properties and events implement the standard Visual Basic drag-and-drop facilities.  See the Visual Basic documentation for these properties.  In addition, TrueGrid implements additional features to simplify the implementation of drag-and-drop interfaces.

Properties

DragIcon	Contains the icon used when the grid is dragged to another location.  Defaults to a shadow of the grid's rectangle.

DragMode	Indicates whether dragging of the grid is manual or automatic.  The setting of this property does not affect the DragCell event, which is sent in all cases.

Events

DragCell	This event is triggered whenever TrueGrid detects an attempt to drag a cell away from the grid.  The cell does not need to be the current cell.  The row, column, and split numbers of the dragged cell are provided as arguments.  The programmer may perform any action in this event.

DragDrop	Indicates that another control has been dropped into the grid.

DragOver	Indicates that another control is being dragged over the grid.


Group:  Determining cell dimensions and location

Normally, the programmer doesn't care exactly where cells are positioned relative to the coordinates of the form.  However, in some cases (such as in the RequestEdit event) it is useful to position other controls relative to the current cell or a column.  These properties allow you to determine the exact location of a cell.  In order to be valid, the cell must be visible.  If the cell is not visible, these properties return 0.

Properties

CellRectHeight	If the current cell is visible, this property returns the height of the current cell in the coordinate system of its parent form or container.  This property cannot be set.

CellRectLeft	If the current cell is visible, this property returns the left boundary of the current cell in the coordinate system of its parent form or container.  This property cannot be set.

CellRectTop	If the current cell is visible, this property returns the top boundary of the current cell in the coordinate system of its parent form or container.  This property cannot be set.

CellRectWidth	If the current cell is visible, this property returns the width of the current cell in the coordinate system of its parent form or container.  This property cannot be set.

ColumnRectLeft	If the specified column is visible, this property returns the left boundary of the column in the coordinate system of its parent form or container.  This property cannot be set.

ColumnRectWidth	If the specified column is visible, this property returns the width of the column in the coordinate system of its parent form or container.  This property cannot be set.

CurCellVisible	This property returns True if the current cell (indicated by RowIndex and ColumnIndex) is visible within the displayed area of the current split.  It returns False if the cell is not visible.  Setting this property to True will scroll the grid so that the cell is in view.  Setting it to False is meaningless and is ignored.


Group:  Finding cells based upon coordinates

TrueGrid supports several properties which can be used to determine, given a point on the grid, what column, row, or split is present at that point.  These properties are especially useful for drag-and-drop applications, which need to know where in the grid data is to be dropped.

Properties

ColumnAtPoint	Returns the column which is beneath the point specified by PointX and PointY.  If there is no column at that position, then this property returns zero.

PointX	Specifies the X coordinate (always in twips) of the point used by ColumnAtPoint, RowAtPoint, or SplitAtPoint.  This property must be set by the programmer before asking for the Column, Row, or Split.

PointY	Specifies the Y coordinate (always in twips) of the point used by ColumnAtPoint, RowAtPoint, or SplitAtPoint.  This property must be set by the programmer before asking for the Column, Row, or Split.

RowAtPoint	Returns the row number which is beneath the point specified by PointX and PointY.  For the headings, zero is returned.

SplitAtPoint	Returns the number of the split which is beneath the point specified by PointX and PointY.  If there is no split at the specified coordinate, zero is returned.


Group:  Programmer control

These are miscellaneous properties and events which are mostly of use to the programmer when customizing the behavior of TrueGrid.

Properties

About	Available only at design time.  Displays an About Box which indicates the current version of TrueGrid.

DataMode	Indicates whether the grid is being used in database mode, or callback mode (in which case data must be provided in the Fetch event, and the Rows and Columns properties must be set by the programmer).

Enabled	If True, then user interaction with the grid will be possible.  If False, the user cannot interact with the grid, but it will still display data and respond to the database.

ExtendRightCol	If True when the the vertical scrolll bar is not needed to display all the columns this property will extend the rightmost column to the grids edge.  If false then the grid will respect the rightmost columns width setting.

Height	Contains the height of the grid in the scale mode of its container.

HelpContextID	Contains the context ID which will be used for the grid if context sensitive help is triggered by using the F1 key at runtime.

Hwnd	This read-only property will contain the Windows HWND handle of the grid.  Although the grid supports complex visual behavior, it consists of a single Windows HWND Window.  Users of this property generally must be familiar with the Windows API in order to use it.

HwndEdit	When editing is in progress, the grid displays a Windows edit control above the current cell.  This read-only property will contain the HWND handle of that window.  If editing is not in progress (EditActive is False), this property returns zero.

Index	The index of the grid, if it is part of a property array.

Left	The left coordinate of the grid in the scale mode of its container.

Name	The name used to identify the grid in Visual Basic code and at design time.

Parent	This property returns the control (a form, frame, or picture control) in which the grid is contained.

RefreshColumn	You can only write to this property, and then only at runtime.  Setting this property to zero refetches all of the data in the current column of all splits.  Setting it to a number other than zero refetches data only in the column indicated.

RefreshRow	You can only write to this property, and then only at runtime.  Setting this property to zero refetches all of the data in the current row of all splits.  Setting it to a number other than zero refetches data only in the row indicated.

Tag	This is a programmer defined text string which can be used for any purpose.

Top	The top coordinate of the grid in the scale mode of its container.

Version	This property returns the current internal version number of the TrueGrid control being used.  The version number is an integer which is incremented for each distributed version, including patches and special releases.

Visible	If True, the grid will be visible to the user.  If False, the grid will not be visible.  Invisible grids still respond to the database unless their Active property is set to False.

Width	The width of the grid in the scale mode of its container.

Events

CheckRows	Enables the programmer to dynamically change the rows property during grid fetching.

Fetch	Called whenever the grid needs data to fill a cell in callback mode.  Not used in database mode.

GotFocus	Triggered whenever the grid receives focus.

KeyDown	Triggered whenever a key is pressed in the grid, or in the editing cell.  This event is triggered before the grid responds to the key, but it cannot be cancelled.  Use the Form KeyPreview property to capture keys before the grid receives them.

KeyPress	Triggered when an ASCII key is pressed.  The keypress can be cancelled if you don't want the grid to respond to the key.

KeyUp	Triggered when a keyboard key returns to the unpressed state.

LostFocus	Triggered whenever the grid loses focus.

MouseDown	This event is triggered when either mouse button goes down and is triggered before the grid recives the mouse event.

MouseMove	Triggered when the user moves the mouse anywhere inside the grid.

MouseUp	Triggered when either mouse button returns to its unpressed state.

Paint	This event is triggered whenever the grid repaints itself.  This occurs frequently in the Windows environment and is generally useful only for special circumstances.  In this event, users familiar with the Windows API may use the Hwnd of the grid (returned by the Hwnd property) to paint special effects, including lines, bitmaps, icons, etc. in appropriate cells of the grid.


Group:  Value list

These are properties and events that relate to using TrueGrid's value list features at run time.

Properties

ColumnButton	Determines whether or not a dropdown button will appear in a given column.

ColumnComboMaxitems	Determines how many items will be displayed in the grid's automatic drop down combo box, before a scroll bar will appear.

VlistColumn	Sets the current value list column for which all value list properties are being read from or written to.  Similar to SplitIndex or ColumnIndex and their respective properties.

VlistCount	Returns the number of entries in the value list.  Can be set to zero to remove the value list for the current value list column.

VlistData	An indexed property that returns the specific items in the value list for the data column.  Corresponds to the Data column In the Field Values Dialog.

VlistDefault	Specifies a default value to be used for the current value list column.  Any value that is not in the value list use the default display value instead.

VlistPicture	If you want to display a picture in place of the value currently displayed then set this property for the corresponding value in the VlistData property and have the ColumnStyle property set with GVLS_TRANSLATE.

VlistStyle	Determines what options will be used for the column's value list.  This property allows you to have the list use translated values, cycle through available option, auto validate, and how the data is to be displayed.

VlistText	If you want a string in place of the value currently displayed then set this property for the corresponding value in the VlistData property and have the ColumnStyle property set with the GVLS_TRANSLATE.

Events

ClickButton	This event is triggered whenever a column with the ClickButton property set to True has the button clicked by the user.  The event passes the current column.  Useful for popping up other controls.

ComboSelect	When using a built-in value list combo, ComboSelect will be fired whenever the user has selected (by clicking) one of the combo items, but has not yet left cell editing mode.

ValidateError	This event is triggered only when the VlistStyle is set to GVLS_VALIDATE.  If the user enters a value that is not in the value list then the ValidateError is fired.  Use this event to determine what to do with new or incorrect values.


Group:  Column Summary

These are properties and events that relate to using TrueGrid's column summary features.

Properties

ColumnSum	Enables the programmer to set the seed of the current column's sum.  You can also read this property at any point to get the current column's sum.

ColumnSumEnable	Boolean value that turns on a column's summary feature.  If set to True then the grid will keep a sum for that column.  If False then the grid will not sum the column.

Events

ColumnSumChange	While the grid does keep the sum internally the programmer may want to constantly display that value.  When there is a change in the column sum then this event is triggered.


The Layout Editor Dialog

Click on a graphic element to display information about that element.

Double-clicking on a column in the Layout Editor will bring up the Properties pop-up.

For instructions on how to use the Layout Editor click "Describe".


Layout Editor Description
The Layout Editor Dialog

The Layout Editor is a tool you can use at design-time to configure many of the TrueGrid properties and gives you a WYSIWYG view of how TrueGrid will appear at runtime.  You run the Layout Editor by clicking on the Layout property in the Visual Basic properties window, or by clicking on a TrueGrid control with the right mouse button.

The Layout Editor provides complete design-time control over the appearance of TrueGrid and allows you to control the following aspects of the grid:

1.	Column Configuration.  You can change the heading, fieldname, format mask, expression, column text fonts and heading fonts, column and heading justification, editability, and visibility of columns.

2.	Locked Columns.  You can lock columns at the left margin (as shown above).

3.	Splits.  You can control the size and position of splits, as well as customize the attributes of columns within each split.  The ability to control splits is available only if you start the Layout Editor while SplitLocked is False.  Normally, it defaults to True, so the split capabilities are disabled.

4.	Value Lists.  Using the Field Values Dialog you can design several types of values lists, including the ability to translate values.  You can also have the data displayed in several formats such as in a dropdown combo, radio buttons, or allowing the user to cycle through available choices.

Moving and Resizing Columns

If columns are currently displayed in the layout editor, you can simply move them or resize them to adjust their appearance.

To move a column, simply grab the column by its heading using the mouse, then drag the column to the left or right.

To resize a column, place the mouse over the vertical separator line between columns and adjust the column size by dragging the line to the left or right.  Columns are always adjusted so that they contain an integral character width, so exact placement may not be possible.

If you resize a column to zero-width, the column is made invisible.  You can still access the column's properties, but you must use the Column Properties Dialog to do so.

Changing Basic Column Properties

If you double-click over a column, or if you click on a column with the right mouse button, a pop-up appears which allows you change basic column properties as well as insert and delete columns:

The popup will look like this:

Each of the options is described below:

Left Justify, Right Justify, and Center allow you to select the justification for the column.  Normally, this affects the justification for both the column text and the heading.  However, if the heading justification was changed in the Column Properties Dialog, then this option affects only the text justification of the column.

Editable allows you to change the editability of the column.  It will be checked if the column is currently editalbe, and unchecked if it is not.

Selecting Heading Text... will allow you to change the heading text of the column.  The cursor will be moved to the heading area of the column and you can change the text displayed there.

Field Name... allows you to change the field name associated with bound columns.  The field name is entered in the heading area, although it will not be displayed there when you have finished changing it.

Selecting Edit Mask... will allow you to enter a Visual Basic Format String for the column.  Like the field name, you enter the edit mask in the heading region, although it will not be displayed when you are done entering it.

Insert Column will insert a new column to the left of the current column.  The newly inserted column will be a bound column, but no field name will be associated with the column initially.

Delete Column will physically delete the column from the layout.  If you inadvertently delete a column, you need to exit the layout editor using the Discard option of the system menu.  This will discard all changes you made during the layout editor session.  When you reenter the layout editor, the column layout will be the same as it was on the original form.

The Properties... option will display the Column Properties Dialog and position you to the current column.  This dialog is a more complete way to edit most of the column characteristics.

Clicking the Value List... option will bring up the Field Values Dialog and allow you to create a value list for the current column.  This dialog allows you to create a value list interatively at design time.

Working With Splits in the Layout Editor

By default, TrueGrid's properties are set so that splits cannot be created directly in the layout editor.  For many people, this behavior is ideal, since the "Locked at Left" option of the Column Properties Dialog will take care of creating a split automatically for locked columns.

However, advanced users may wish to use the split capabilities for more sophisticated operations.  In such cases, all of the capabilities of splits are available at design time.

To enable splits in the layout editor, you must be sure that the SplitLocked property is set to False, which unlocks the displayed split.  Now, upon entering the layout editor, a small split create box will appear at the leftmost extent of the horizontal scrollbar.  You can drag the box interactively to create a new split.

Once splits exist in the layout editor, you can choose to have changes you make to columns be applied only to the column within the currently selected split.  To do so, you need to make sure SplitPropsGlobal is set to False, which allows you to have access to split-specific behavior.  Although most properties can be applied on a per-split basis, some properties (FieldName, EditMask, Bound/Unbound/Calculated column state) are global properties of a column.  The Column Properties Dialog will automatically highlight column-global properties in blue so you know which settings apply to the column globally, and which apply on a per-split basis.


Layout Editor Caption

The caption indicates the name of the control (specified by the Name property) as well as the legend "Layout Editor" so you know which control you are editing and that you are presently in the layout editor.  You can reposition the layout editor on your screen by holding the mouse down over the caption bar.


Inactive Headings

Only one split (section of the layout) is active at one time.  The inactive headings are shown using the InactiveForeColor and InactiveBackColor to differentiate them from the active split.  You can customize these colors on a per-split basis by leaving the layout editor, assuring that SplitPropsGlobal is False, then setting the headings while SplitIndex points to the proper split number.


Active Split Headings

Only one split (section of the layout) is active at one time.  The active split is shown using the HeadBackColor and HeadForeColor settings for the grid.  You can customize these colors on a per-split basis by leaving the layout editor, assuring that SplitPropsGlobal is False, then setting the headings while SplitIndex points to the proper split number.


Locked Columns

Locked columns are always at the left, and are really just a special type of split.  Locked columns are easily created by using the Locked at Left checkbox in the Column Properties dialog and TrueGrid automatically sets up the split properties for you.  If you master the proper split properties, you can create locked columns (or variations) yourself.


Column Within a Split

The columns within a split can be modified by double-clicking on the column (or by using the right mouse button).  This split is inactive (note the heading color).  You can move the columns (by holding down the mouse on their heading), or adjust their size by moving the line between columns.  When you attempt to edit a column within a split, the Layout Editor automatically makes the split the active split.  You can simply click on a split to make it the active split if you want.  If SplitPropsGlobal is False, then each split has its own column settings; otherwise, when you change column settings, they are changed for all splits.


Column Within a Split

The columns within a split can be modified by double-clicking on the column (or by using the right mouse button).  This split is the active split (note the heading color).  You can move the columns (by holding down the mouse on their heading), or adjust their size by moving the line between columns.  When you attempt to edit a column within a split, the Layout Editor automatically makes the split the active split.  You can simply click on a split to make it the active split if you want.  If SplitPropsGlobal is False, then each split has its own column settings; otherwise, when you change column settings, they are changed for all splits.


Horizontal Scroll Bar

The horizontal scroll bar allows you to scroll columns from left to right to examine them, or change their size.  Each split has its own horizontal scrollbar and the position can be different for each split.  The position of the scrollbars in the layout editor is not saved.  When you run your application, all of the splits will be positioned to their leftmost column.


Vertical Scrollbar

Normally, there is only one vertical scrollbar (see SplitGroup for a discussion of multiple vertical scrolliing).  If you have sample data displayed in the cells (shown here), then the vertical scrollbar allows you to scroll through the sample data; otherwise, the scrollbar does nothing.  The scrollbar won't be shown if you have disabled it using the VertScrollbar property.


Scrollbar Placeholder

Locked columns have no horizontal scrollbar, and instead display a grey area where the scrollbar would be.  If the grid itself has no horizontal scrollbars at all (due to the setting of HorzScrollbar for example), then this grey area will be omitted as well.


"New Split" Box

The small black box at the leftmost side of the leftmost split (locked columns don't have them) can be used to create new splits interactively.  All you need to do is drag the new split box to the right and a new split will be created.  The new split inherits all of the column settings from the split immediately to its right.  Unless you have SplitLocked set to False, you won't be able to create splits in the Layout Editor.  Once splits are created, you can lock them using the SplitLocked property so the user can't change them.


"Resize Split" Box

Between splits, the small black box allows you to move the boundary between splits.  Just drag it to the left or right to resize the split, or all the way to the left or right boundary to delete a split.  Unless you have SplitLocked set to False, you won't be able to resize a split.  Once you have set the split sizes, however, you can change SplitLocked so that the user can no longer adjust them.


System Menu

The system menu contains several options for controlling the overall Layout editor, including options for displaying sample data, clearing the grid, and discarding changes before returning to Visual Basic.


"Move" Option

The Move option allows you to move the layout editor anywhere on your screen.  You can also move the layout editor by grabbing the caption area.


"Close" Option

The Close option will close the layout editor, save all changes you have made to the layout, and return to Visual Basic.


"Discard" Option

Choosing the Discard option will ignore any changes you have made during this Layout Editor session and return to the Visual Basic design environment.  The original layout will remain intact in the TrueGrid control on your form.


"Clear Fields" Option

Selecting Clear Fields will remove all splits and columns, making the current layout completely blank.  If you then choose "Close", all layout information will be deleted and the grid will return to its initial state with no design-time layout at all.  If you inadvertently choose "Clear Fields", then just choose Discard and return to Visual Basic; the original control layout will remain intact.


"Show Sample Data" Option

This option will toggle the layout editor display of sample data.  The sample data is useful for showing how text formatting within columns will look.  It also displays the row and column numbers in the columns, which is useful for knowing exactly what the column indexes are for use in your code.


"Layout Editor Help" Option

This option will bring up the Layout Editor Help screen.


Column Properties Dialog

Click on a graphic element to display information about that element.

For instructions on how to use the Column Properties Dialog click "Describe".


Column Properties Dialog Description
Column Properties Dialog

Introduction to the Column Properties Dialog

The column properties dialog was added in TrueGrid 2.0 to make it easier to change many of the column properties.  You invoke the column properties dialog by bringing up the Properties Pop-up in the Layout Editor.  The column you clicked on to bring up the properties popup will be the initial column displayed in this dialog.

Any changes you make to the current column can be discarded by clicking Cancel (which returns you to the Layout Editor).  Clicking OK will save the changes you made.  You can move from column to column using the scrollbar at the left, and insert new columns with New as well as delete existing columns with Delete.  The Update button will update the changes to the current column without leaving the properties dialog.

Once changes are made to a column, and updated, the changes are immediately reflected in the layout grid.  If you make changes to properties which affect the appearance of text in columns, you may want to be sure you select Show Sample Data from the system menu of the Layout Editor.  TrueGrid will fill the grid with sample data so you can see the effect of your changes.

Properties Affected by the Dialog

The column properties dialog controls the following properties:

ColumnExpression	Corresponds to the expression typed in the Expression area of the dialog box.

ColumnField	Choosing a fieldname in the Field Name combo, or typing one in, changes this property.

ColumnFontStyle	Clicking on the text Bold, Underline, or Italic checkboxes changes this property from -1 (meaning the text font is inherited from the grid) to the appropriate font style.

ColumnHeadFontStyle	Clicking on the heading Bold, Underline, or Italic checkboxes changes this property from -1 (meaning the heading font is inherited from the grid) to the appropriate font style.

ColumnName	Corresponds to the value typed in the Heading field.

ColumnSize	Changed by setting the value of the Limit entry in the dialog.

ColumnStyle	The ColumnStyle property contains bits which indicate the disposition of the column justification and editability.  These bits correspond to the Heading Justification and Text Justification combos as well as the Editable checkbox.

ColumnType	Changed by clicking on the Bound, Unbound, or Calculated column radio buttons.

ColumnVisible	The Visible checkbox will set this property.

ColumnWidth	Changed by setting the value of the Width entry in the dialog.

ColumnWordWrap	Check the WordWrap check box.

EditMask	Changing the Format$ entry sets this property.

There is no property corresponding to the Locked at Left checkbox (see below).

Locking Columns at the Left Margin

The Locked at Left checkbox is a convenience feature designed to simplify the use of splits.  Locking columns is a common use for splits, and since several properties must be set to accomplish this, the Locked at Left process automates a common task.

When you click Locked at Left, TrueGrid will automatically create a split and set the proper properties so that the selected column appears in the leftmost part of the grid.  Once locked, you can treat the column just like any other, changing its width and other characteristics without concern for its locked status.

To unlock the column, just uncheck the box.

How "Locked at Left" Works

Once you master the split properties (see the advanced user's overview for Realizing the Full Potential of Splits) you can create more sophisticated effects than the simple locked column.  It may be useful, in such cases, to know exactly what "Locked at Left" does.

When you lock a column, TrueGrid does the following:

1.	If there is no split at the left, TrueGrid creates one.

2.	TrueGrid assures that all of the columns which are locked have ColumnVisible set to True in the leftmost split, and have ColumnVisible set to False in all of the remaining splits.  Note that all columns are always present in all splits, but it is the visibility state of the column that makes it appear where you want it.

3.	TrueGrid makes sure that the leftmost split has its SplitLocked property set to True so that it is a fixed split and the user cannot remove or resize it.

4.	TrueGrid sets the SplitSizeMode of the leftmost split to "2 - Number of columns" so that the split will always conform to the size of an integral number of columns.

5.	TrueGrid sets the SplitSize of the leftmost split to equal the exact number of locked columns.  This causes TrueGrid to display only the locked columns and to keep the split at the proper size.

So long as the above properties remain consistent, TrueGrid will continue to support the "Locked at Left" behavior in the Layout editor.  If you modify the SplitSizeMode, SplitSize, or SplitLocked setting for the left split, or if the locked columns are not invisible in all other splits, TrueGrid assumes that you know what you are doing and the "Locked at Left" checkbox will be grayed-out.

Although there is no corresponding property at runtime, the utility functions TgLockColumnLeft, TgLockColumnRight, and TgUnlockColumn can be used to manipulate locked columns at runtime.

More About Splits

By default, you don't need to know much about splits, but once you learn how to use them, TrueGrid enables you to control many split characteristics in the column properties dialog.

The column properties dialog is affected by splits in two ways:

1.	When you enter the column properties dialog, not only are you positioned at a particular column, but if you have multiple splits, you are positioned within a particular split.  You can tell which split you are in by looking at the TrueGrid headings in the layout.  The current split will use the active heading color while all other splits will use the inactive heading color.

2.	Normally, changing column properties will change the properties in all splits.  However, if you have SplitPropsGlobal set to False, then TrueGrid allows you to make changes to columns in only the current split.  To make this clearer, the column properties dialog will change slightly if SplitPropsGlobal is False to indicate which settings are global, and which are applied only to the current split.


Column Number

The column number shows the column currently being edited.  When you click on the layout editor to bring up the properties pop-up, the column you click over will be the column initially displayed.  Use the scrollbar at the left to move from column to column.


Scrollbar for Changing Columns

Use the scrollbar at the left to change from column to column.  When moving to another column, information for the current column will be automatically updated to the grid displayed in the layout editor.  If you want to discard information you've changed, then click Cancel instead.


Bound, Unbound, or Calculated Column Radio Buttons

Bound columns require a field name to be specified, which will automatically be fetched and updated by TrueGrid.  For unbound columns, you need to write code in the UnboundFetch event to fill the column with data when it is needed.  When calculated columns are selected, an expression can be entered at the bottom of the dialog.  TrueGrid will automatically calculate the expression and fill the column with data for you.  These radio buttons correspond to setting the ColumnType property in your code at runtime.


Heading Text

The heading field will be displayed at the top of the column.  The heading can be as long as you like and will wrap within the heading area if HeadingHeight has been set large enough to accomodate more than one row.  The heading text can be changed at runtime using the ColumnName property.


Column Display Width

The Width setting specifies the size of the column as it is displayed.  This value is specified in characters.  Changing this value will change the actual displayed width of the column in the layout editor.  You can also change the width by moving the vertical lines in the Layout Editor.  At runtime, you can inspect and change this value using the ColumnWidth property.


Column Data Entry Limit

This setting specifies the maximum number of characters which can be entered into the field.  It is independent of the column's display width.  The default value (if non-zero) is derived from the database definition.  If you set this value to zero, then TrueGrid imposes no data entry limit.  At runtime, you can inspect and change this value using the ColumnSize property.


Format$ String

This combo box specifies the Visual Basic Format String to be used for displaying data in the column.  This does not affect the storage format of the data, but only the displayed value.  The drop-down contains a list of frequently used formats.  However, you can type directly into the text area to enter your own format string, or to clear the format string for the column.  At runtime, this setting can be changed and inspected using the EditMask property.


Column Field Name

This item is available only for bound columns.  It contains the database field name to which the column is bound.  If TrueGrid is linked to a data control, then the drop-down portion will contain a list of valid fieldnames for you to choose from.  However, you can type directly into the text area of the combo if you know the fieldname, or if the fieldname will be valid at runtime even though it is not available at design time.  At runtime, this setting can be changed and inspected using the ColumnField property.


Calculated Expression

This item is available only for calculated columns.  When enabled, you must enter a valid Visual Basic Expression consising of Visual Basic Operators and functions supported by TrueGrid.  When you update the column information, TrueGrid checks the expression for validity.  At runtime, you can inspect and change this value by using the ColumnExpression property.


Heading Justification Combo

This combo box allows you to select Left, Right, or Centered justification styles for the current column heading.  At runtime, this setting can be changed and inspected using the ColumnStyle property.


Column Text Justification Combo

This combo box allows you to select Left, Right, or Centered justification styles for the current column text.  In order to see the effect of this setting, you need to turn the sample data display in the Layout Editor system menu.  At runtime, this setting can be changed and inspected using the ColumnStyle property.


Heading Font Bold

This checkbox applies bold font characteristics for the heading of the current column.  If the checkbox is grayed-out, then all font characteristics are currently inherited from the default grid font characteristics.  Checking either the bold, italic, or underline boxes will force the column to override default settings and all three boxes will no longer be grayed-out.  At runtime, this setting can be changed and inspected using the ColumnHeadFontStyle property.


Heading Font Italic

This checkbox applies italic font characteristics for the heading of the current column.  If the checkbox is grayed-out, then all font characteristics are currently inherited from the default grid font characteristics.  Checking either the bold, italic, or underline boxes will force the column to override default settings and all three boxes will no longer be grayed-out.  At runtime, this setting can be changed and inspected using the ColumnHeadFontStyle property.


Heading Font Underline

This checkbox applies underlined font characteristics for the heading of the current column.  If the checkbox is grayed-out, then all font characteristics are currently inherited from the default grid font characteristics.  Checking either the bold, italic, or underline boxes will force the column to override default settings and all three boxes will no longer be grayed-out.  At runtime, this setting can be changed and inspected using the ColumnHeadFontStyle property.


Column Text Font Bold

This checkbox applies bold font characteristics for the text of the current column.  The change will not be apparent in the grid unless the Show Sample Data option is selected in the Layout Editor system menu.  If the checkbox is grayed-out, then all font characteristics are currently inherited from the default grid font characteristics.  Checking either the bold, italic, or underline boxes will force the column to override default settings and all three boxes will no longer be grayed-out.  At runtime, this setting can be changed and inspected using the ColumnFontStyle property.


Column Text Font Italic

This checkbox applies italic font characteristics for the text of the current column.  The change will not be apparent in the grid unless the Show Sample Data option is selected in the Layout Editor system menu.  If the checkbox is grayed-out, then all font characteristics are currently inherited from the default grid font characteristics.  Checking either the bold, italic, or underline boxes will force the column to override default settings and all three boxes will no longer be grayed-out.  At runtime, this setting can be changed and inspected using the ColumnFontStyle property.


Column Text Font Underline

This checkbox applies underlined font characteristics for the text of the current column.  The change will not be apparent in the grid unless the Show Sample Data option is selected in the Layout Editor system menu.  If the checkbox is grayed-out, then all font characteristics are currently inherited from the default grid font characteristics.  Checking either the bold, italic, or underline boxes will force the column to override default settings and all three boxes will no longer be grayed-out.  At runtime, this setting can be changed and inspected using the ColumnFontStyle property.


Locked At Left Setting

Checking this box causes the current column to be locked at the leftmost portion of the grid.  In actuality, TrueGrid creates a split at the left of the grid and automatically sets the proper properties to lock this column.  Unchecking the box will unlock the column.  If this box is greyed, then you have modified the layout of splits so that TrueGrid can no longer recognize the left split as the one containing locked columns.  There is no property equivalent for this checkbox.


Column Visible Checkbox

If this box is checked, then the current column is visible in the grid.  If unchecked then the column will not be visible.  Upon exiting the layout editor, any invisible columns are physically removed from the layout rather than being stored. (unless Preserve is also checked).  At runtime, column visibility can be controlled using the ColumnVisible property.


Preserve Checkbox

Checking this box will preserve a column as part of the design-time layout, even if the it is invisible in all splits of the grid.  Normally, upon exit from the Layout Editor, any columns which are completely invisible are removed from the layout to conserve runtime memory.  Sometimes, it is useful to preserve hidden columns for some runtime purpose (such as unbound or calculated columns which depend upon their values).  If a column is visible, this checkbox is grayed-out.


Column Editable Checkbox

If this box is checked, then the current column will be editable by the user.  If unchecked, no editing can take place in the column.  At runtime, this setting may be changed by using the ColumnStyle property.  Even if a column is marked as editable, editing will not be allowed if the Editable property is set to False for the grid, or if the column's split is marked as uneditable with the SplitEditable property.


Create New Column Button

Clicking on this button will insert a new column immediately to the left of the the current column.  Any changes to the current column will be saved before the new column is created.


Delete Current Column Button

Clicking on this button will delete the current column from the layout.  If the column occurs in more than one split, it will be removed from all splits simultaneously.  Any changes to the current column will be lost.  If you want a column to be visible in one split and not in another, don't use the Delete button, but rather make the column invisible in the splits where you do not want it to appear.  Split-specific column changes are only possible if SplitPropsGlobal is set to False.


Update Column Properties Button

Clicking on this button will update the properties for the current column so that they are reflected in the layout editor grid.  Moving to a new column, adding a new column, or clicking OK will also update the current column properties.


Cancel Current Column Edits

Clicking on this button will discard any changes made to the current column only and return to the layout editor grid.  Any changes made to other columns will still be permanent unless the Discard option is used in the Layout Editor system menu.


Help Button

Clicking on this button will bring up the on-line help page for the column properties dialog.  Help can also be obtained by pressing F1 in the column properties dialog or in the layout editor.


OK Button

Clicking on this button will save the current column definition and return to the layout editor grid.


Value list.. button

Clicking this button will bring up the Field Values Dialog and allow you to create a value list for the current column.  This dialog allows you to create a value list interatively at design time.


ColumnWordWrap Check Box

This check box enables you to have the current column truncate the data at the right-hand side of the column or have it wrap the last word to the next line.  This property sets the ColumnWordWrap property.


Properties Pop-up (Layout Editor)

The properties pop-up can be accessed by double-clicking on a column in the layout editor, or by clicking on a column with the right mouse button.  Each of the entries in this dialog corresponds to entries in the Column Properties Dialog but they are included here as well for convenience.


Left Justify (pop-up)

Allows you to select left justification for the column.  Normally, this affects the justification for both the column text and the heading.  However, if the heading justification was changed in the Column Properties Dialog, then this option affects only the text justification of the column.


Center (pop-up)

Allows you to select centered text for the column.  Normally, this affects the justification for both the column text and the heading.  However, if the heading justification was changed in the Column Properties Dialog, then this option affects only the text justification of the column.


Right Justify (pop-up)

Allows you to select right justified text for the column.  Normally, this affects the justification for both the column text and the heading.  However, if the heading justification was changed in the Column Properties Dialog, then this option affects only the text justification of the column.


Editable (pop-up)

The editable option allows you to change the editability of the column.  It will be checked if the column is currently editalbe, and unchecked if it is not.


Heading Text... (pop-up)

This option will allow you to change the heading text of the column.  The cursor will be moved to the heading area of the column and you can change the text displayed there.


Field Name... (pop-up)

Selecting this option allows you to change the field name associated with bound columns.  The field name is entered in the heading area, although it will not be displayed there when you have finished changing it.


Edit Mask... (pop-up)

Selecting Edit Mask... will allow you to enter a Visual Basic Format String for the column.  Like the field name, you enter the edit mask in the heading region, although it will not be displayed when you are done entering it.


Insert Column (pop-up)

Insert Column will insert a new column to the left of the current column.  The newly inserted column will be a bound column, but no field name will be associated with the column initially.


Delete Column (pop-up)

This option will physically delete the column from the layout.  If you inadvertently delete a column, you need to exit the layout editor using the Discard option of the system menu.  This will discard all changes you made during the layout editor session.  When you reenter the layout editor, the column layout will be the same as it was on the original form.


Properties... (pop-up)

The Properties... option will display the Column Properties Dialog and position you to the current column.  This dialog is a more complete way to edit most of the column characteristics.


Value List... (pop-up)

Clicking the Value List... option will bring up the Field Values Dialog and allow you to create a value list for the current column.  This dialog allows you to create a value list interatively at design time.


Field Values Dialog

Click on a graphic element to display information about that element.

For instructions on how to use the Field Values dialog click "Describe".


Field Value Description
Field Values Dialog

Version 2.1 of TrueGrid adds a powerful new feature called "value list".  Using this feature you can dramatically enhance the display of the grid.  At design time you can set up these features using the Field Value Dialog.  To access the Field Values dialog click on the Value List option from the Properties pop-up or click the Value List... button in the Column Properties Dialog.  The column you clicked on to bring up the properties popup will be the initial column displayed in this dialog.

Any changes you make to the current column's value list can be discarded by clicking Cancel (which returns you to the previous dialog).  Clicking OK will save the changes you made.

Once you are in this dialog you can specify the valid values for a column in the data column.  A common simple use is to check the "cycle on click" check box in which case when the user clicks on that column it will display each value in the data column in succession.  You could also check the "Auto Validate" check box and the user would then be able to enter only values specified in the data column.

Once the data is entered you then need to choose how you want to display the data.  You can click on one of the three radio buttons to choose how you want the data displayed.  If you select the "Text" button the data will be displayed normally.  If you check the "Radio buttons" option then the grid will take the values in the data column and display them as radio buttons.  Selecting the "Combo" option will result in a dropdown combo box being automatically displayed with the values taken from the data colum.  If you check the "Sorted" check box in conjunction with the "Combo" option then the values will be displayed in sorted order.

If you want a certain value to be displayed even if it is not in the value list then select that value and click the "Default" check box.  This value will be displayed for any value not listed in the data column.

Translated values and pictures

Using value list to automate the data entry is great but one of the most important features that TrueGrid enables you to do is substitute database data with your own!  If you click on the "Translate Values" check box you will notice that another column appears in the grid with the heading "User value".  Using this column it is possible to substitute cryptic values such as 0 and -1 with True/False, Yes/No, or whatever you heart desires.  Neat huh?  It gets better.  Let's say that you want to show a simley face and a frowning face.  The toughest part is getting the bitmaps (we stole them from WinMine).

Once you have the bitmaps simply select the row you want the picture to appear in and click the "Picture..." button.  A file open dialog appears and you can select your bitmap.  When you return the bitmap will be displayed in the right hand side of the grid.  If you choose to use pictures then it is highly recommended that you use the Text option for display.  You can still use the "Cycle on click" option, in fact this is recommended when using things like check boxes.  However, using AutoValidate doesn't make much sense since the user can't "enter" the picture.

Properties Affected by the Dialog

The field values dialog controls the following properties:

ColumnButton	Automatically set to True if the combo option is selected.

VlistCount	Automatically set to the number of values in the data column.

VlistData	An indexed property that corresponds to the values in the data column.

VlistDefault	Correspondes to the Default check box.

VlistPicture	An indexed property that corresponds to any pictures used in the user value column.

VlistStyle	Set using a combination of the display values frame, and the cycle on click, auto validate, and translate values check boxes.

VlistText	An indexed property that corresponds to the text values used in the user value column.


Layout Editor Caption

The caption indicates the name of the column (specified by the ColumnName property) as well as the legend "Field Values..." so you know which column you are editing and that you are presently in the field values dialog.  You can reposition the field values dialog on your screen by holding the mouse down over the caption bar.


Data Value Column

This column holds the values that represent the values in the database.  In this column you should specify all the values you want the user to be able to enter (if you click Auto Validate), or cycle through (if you click Cycle on Click).  If the Translate values check box is turned off these are the values that will be displayed in the grid at run-time.


User Value Column

This column holds the value the programmer wants the user to see.  These values can either be text or picutres.  This column is only present when the "Translate Values" check box is turned on.  In this column you should specify all the values you want the user to be able to enter (if you click Auto Validate), or cycle through (if you click Cycle on Click).


Data Column Entries

These are the values that TrueGrid will compare against the database (or array) to either substitue with the translated value, auto validate, or cycle through, depending on which options are turned on.  The number of entries can be checked at run-time using the VlistCount.


User Value Entries

These are the values that TrueGrid will display in the grid in place of it's corresponding value in the data column.  These values can be either text or pictures.  You can check these values at run time using the VlistText or VlistPicture depending on contents of the column.


OK Button

Clicking on this button will save the current value list definitions and return to the layout editor or the column properties dialog (depending on which one you entered the dialog from).


Cancel Button

Clicking on this button will discard any changes made to the current value list and return to the layout editor or column properties dialog (depending on which one you entered the dialog from).


Picture Button

Clicking this button allows you to have BMP files displayed in the User value column.  When you click this button a File Open dialog will pop up and allow you to select a BMP file.  The picture will then appear in the current row in the user column.


Display as Text

This is the default display method.  If you have this option chosen then the grid will display the Data value or the User value, depending on the Translate Values check box, in standard format.


Display as Radio Button

This option allows you to display a set of Radio buttons in place of the standard text layout.  In each cell there will be a radio button for each option listed in the data or user value column.


Display as Combo Box

Using this option the grid will display the data in a standard text layout.  However if the user clicks on a column with this setting a ColumnButton and an automatic dropdown combo will appear for the user to select from.  You can control the number of items displayed in the dropdown before a scroll bar appears by setting the ColumnComboMaxItems


Sorted Check Box

This check box is only enabled when the Combo option is selected.  If Sorted is checked the values that appear in the dropdown combo will be in sorted order.


Translate Values Check Box

If you want the values in the data column to be substituted with different values then check the translate check box.  When checked a second column appears in the grid and allows you to enter in values to be displayed in the grid at run time in place of the values in the data column.


Auto Validate Check Box

If checked then the user will only be able to enter in values from the value list.  If the user tries to enter in a value that is not in the list then the grid will beep and stay in edit mode until the user enters a valid value.


Cycle on Click Check Box

If checked the users can cycle through all the values in the value list simply by clicking on the cell.  Also the user will only be able to edit the cell by explicitly typing in a value.


Default Value Check Box

If checked the current column in the value list will change the font to an italic.  This value will then be used for any value that is in the database or typed in by the user that is not in the value list.


See Also

Properties:

Version


See Also

Overviews:

How TrueGrid reacts to Dynaset changes


See Also

Properties:

ColumnAddRegexAttr

ColumnHasRegexAttr

HasRegexAttr

ParamBackColor

ParamFontStyle

ParamForeColor

ParamStatus

Overviews:

Priority of Colors and Fonts Applied to Cells

How TrueGrid applies colors and fonts to a cell

Introduction to regular expressions


See Also

Properties:

AllowTabs

SplitSelectable

SplitTabMode

WrapCellPointer

Overviews:

Mouse and keyboard interaction with splits


See Also

Properties:

AllowTabs

SplitSelectable

SplitTabMode

TabCapture

WrapCellPointer

Overviews:

Mouse and keyboard interaction with splits


See Also

Properties:

BookmarkList

SelectMode

Events:

MarkChange

QueryMark

Overviews:

Multiple selection overview

Using the BookmarkList to highlight query result rows


See Also

Properties:

BookmarkCount

SelectMode

Events:

MarkChange

QueryMark

Overview

Multiple selection overview

Using the BookmarkList to highlight query result rows


See Also

Properties:

ReferenceRow

RowIndex

Rows

TopRow

Events:

RowChange

TopRowChange

Overviews:

Row numbers and what they mean


See Also

Properties:

CellRectLeft

CellRectTop

CellRectWidth

CurCellVisible


See Also

Properties:

CellRectHeight

CellRectTop

CellRectWidth

CurCellVisible


See Also

Properties:

CellRectHeight

CellRectLeft

CellRectWidth

CurCellVisible


See Also

Properties:

CellRectHeight

CellRectLeft

CellRectTop

CurCellVisible


See Also

Properties:

AddRegexAttr

ColumnHasRegexAttr

HasRegexAttr

ParamBackColor

ParamFontStyle

ParamForeColor

ParamStatus

Overviews:

Priority of Colors and Fonts Applied to Cells

How TrueGrid applies colors and fonts to a cell

Introduction to regular expressions


See Also

Properties:

PointX

PointY

RowAtPoint

SplitAtPoint

Events:

DragCell

Overviews:

Dragging cells or rows from a grid to another control


See Also

Properties:

ColumnForeColor

Overviews:

How TrueGrid applies colors and fonts to a cell

TrueGrid color settings and font styles


See Also

Events:

FetchAttributes

Overviews:

How TrueGrid applies colors and fonts to a cell


See Also

Properties:

ColumnText

Events:

Update

Validate

Overviews:

Data validation techniques

Overview of cell editing

TrueGrid live data updates and Validate handlers


See Also

Properties:

ColumnType

Overviews:

What are unbound and calculated columns?


See Also

Events:

FetchMargins


See Also

Properties:

ColumnName

ColumnSize


See Also

Properties:

ColumnHeadFontStyle

Overviews:

How TrueGrid applies colors and fonts to a cell

TrueGrid color settings and font styles


See Also

Properties:

ColumnBackColor

Overviews:

How TrueGrid applies colors and fonts to a cell

TrueGrid color settings and font styles


See Also

Properties:

AddRegexAttr

ColumnAddRegexAttr

HasRegexAttr

ParamBackColor

ParamFontStyle

ParamForeColor

ParamStatus

Overviews:

Priority of Colors and Fonts Applied to Cells

How TrueGrid applies colors and fonts to a cell

Introduction to regular expressions


See Also

Properties:

ColumnFontStyle

Overviews:

How TrueGrid applies colors and fonts to a cell

TrueGrid color settings and font styles


See Also

Properties:

ColumnIndex

Columns

LeftColumn

RightColumn

Events:

ColumnChange

LeftColChange


See Also

Properties:

ColumnField

Overviews:

Design time column layouts using the Layout Editor


See Also

Properties:

ColumnIndex

Overviews:

Design time column layouts using the Layout Editor


See Also

Properties:

ColumnRectWidth

CellRectLeft


See Also

Properties:

ColumnRectLeft

CellRectWidth


See Also

Properties:

ColumnIndex

LeftColumn

RightColumn

Events:

ColumnChange

LeftColChange

Overviews:

Design time column layouts using the Layout Editor


See Also

Properties:

ParamBackColor

ParamFontStyle

ParamForeColor

ParamStatus

SetStatusAttr

Overviews:

Priority of Colors and Fonts Applied to Cells

How TrueGrid applies colors and fonts to a cell


See Also

Properties:

ColumnField


See Also

Overviews::

Design time column layouts using the Layout Editor


See Also

Properties:

ColumnExpression

Events:

UnboundFetch


See Also

Properties:

ColumnChanged

Text

ReferenceRow

Events:

Update

Validate

Overviews:

Data validation techniques

Overview of cell editing

TrueGrid live data updates and Validate handlers


See Also

Overviews:

Design time column layouts using the Layout Editor


See Also

Properties:

ColumnSize

Overviews:

Design time column layouts using the Layout Editor


See Also

Properties:

SplitLocked

Overviews:

Allowing the user to reconfigure grid appearance at runtime


See Also

Properties:

CellRectHeight

CellRectLeft

CellRectTop

CellRectWidth

ExposeCellMode


See Also

Property

ColumnChanged

Events:

Change

Update

Validate


See Also

Overviews:

Introduction to TrueGrid Callback mode


See Also

Properties:

DataSourceHwnd

Overviews:

How TrueGrid reacts to Dynaset changes


See Also

Properties:

DataSource

Overviews:

How TrueGrid reacts to Dynaset changes


See Also

Properties:

ColumnAtPoint

PointX

PointY

RowAtPoint

SplitAtPoint

Overviews:

Dragging cells or rows from a grid to another control


See Also

Properties:

EditActive

EditDropDown

Events:

EnterEdit

ExitEdit

RequestEdit

SplitEditable

Overviews:

Data validation techniques

Overview of cell editing

TrueGrid live data updates and Validate handlers


See Also

Properties:

Editable

SplitEditable

Events:

EnterEdit

ExitEdit

RequestEdit

Overviews:

Data validation techniques

Overview of cell editing

TrueGrid live data updates and Validate handlers


See Also

Properties:

EditForeColor

Overviews:

TrueGrid color settings and font styles


See Also

Properties:

EditActive

Events:

EnterEdit

ExitEdit

Overviews:

Data validation techniques

Overview of cell editing

TrueGrid live data updates and Validate handlers


See Also

Properties:

EditBackColor

Overviews:

TrueGrid color settings and font styles


See Also

Overviews:

Design time column layouts using the Layout Editor


See Also

Properties:

CurCellVisible


See Also

Overviews:

How TrueGrid reacts to Dynaset changes


See Also

Properties:

AddRegexAttr

ColumnAddRegexAttr

ColumnHasRegexAttr

ParamBackColor

ParamFontStyle

ParamForeColor

ParamStatus

Overviews:

Priority of Colors and Fonts Applied to Cells

How TrueGrid applies colors and fonts to a cell

Introduction to regular expressions


See Also

Properties:

HeadFontStyle

HeadForeColor

Overviews:

How TrueGrid applies colors and fonts to a cell

TrueGrid color settings and font styles


See Also

Properties:

HeadFontStyle

HeadBackColor

Overviews:

How TrueGrid applies colors and fonts to a cell

TrueGrid color settings and font styles


See Also

Properties:

HeadBackColor

HeadForeColor

Overviews:

How TrueGrid applies colors and fonts to a cell

TrueGrid color settings and font styles


See Also

Properties:

HeadBackColor

HeadFontStyle

HeadForeColor

Headings

LinesPerRow


See Also

Properties:

HeadBackColor

HeadFontStyle

HeadForeColor

HeadingHeight

SplitGroup


See Also

Properties:

VertColor

Overviews:

TrueGrid color settings and font styles


See Also

Properties:

VertLines

Overviews:

How to give the grid a 3-dimensional appearance


See Also

Properties:

VertScrollbar


See Also

Properties:

InactiveForeColor

Overviews:

TrueGrid color settings and font styles


See Also

Properties:

InactiveBackColor

Overviews:

TrueGrid color settings and font styles


See Also

Overviews:

Creating locked columns in the layout editor

Creating splits at design time using the layout editor

Design time column layouts using the Layout Editor

Using the column properties dialog

Using the layout editor to configure columns in splits


See Also

Properties:

RemoveSplit

Splits

Overviews:

Creating splits at design time using the layout editor

Introduction to TrueGrid splits

Overview of TrueGrid splits


See Also

Properties:

ColumnIndex

Columns

RightColumn

Events:

ColumnChange

LeftColChange

Overviews:

Design time column layouts using the Layout Editor


See Also

Properties:

HeadingHeight


See Also

Properties:

MarqueeUnique

Overviews:

Changing the appearance of the marquee


See Also

Properties:

MarqueeStyle

Overviews:

Changing the appearance of the marquee


See Also

Properties:

Editable

EditActive

Events:

Change

EnterEdit

ExitEdit

RequestEdit

Overviews:

Data validation techniques

Overview of cell editing

TrueGrid live data updates and Validate handlers


See Also

Properties:

AddRegexAttr

ColumnAddRegexAttr

ColumnSetStatusAttr

ParamFontStyle

ParamForeColor

ParamStatus

SetStatusAttr

Overviews:

How TrueGrid applies colors and fonts to a cell


See Also

Properties:

AddRegexAttr

ColumnAddRegexAttr

ColumnSetStatusAttr

ParamBackColor

ParamForeColor

ParamStatus

SetStatusAttr

Overviews:

How TrueGrid applies colors and fonts to a cell


See Also

Properties:

AddRegexAttr

ColumnAddRegexAttr

ColumnSetStatusAttr

ParamBackColor

ParamFontStyle

ParamStatus

SetStatusAttr

Overviews:

How TrueGrid applies colors and fonts to a cell


See Also

Properties:

AddRegexAttr

ColumnAddRegexAttr

ColumnSetStatusAttr

ParamBackColor

ParamFontStyle

ParamForeColor

SetStatusAttr

Overviews:

How TrueGrid applies colors and fonts to a cell


See Also

Properties:

ColumnAtPoint

PointY

RowAtPoint

SplitAtPoint

Events:

DragCell

Overviews:

Dragging cells or rows from a grid to another control


See Also

Properties:

ColumnAtPoint

PointX

RowAtPoint

SplitAtPoint

Events:

DragCell

Overviews:

Dragging cells or rows from a grid to another control


See Also

Properties:

BottomRow

ColumnText

CellRectLeft

CellRectTop

CellRectWidth

CellRectHeight

RowIndex

Rows

TopRow

Events:

FetchAttributes

FetchMargins

QueryMark

RowChange

TopRowChange

UnboundFetch

Overviews:

Row numbers and what they mean


See Also

Properties:

RefreshRow

Overviews:

Introduction to TrueGrid Callback mode


See Also

Properties:

RefreshColumn

Overviews:

Introduction to TrueGrid Callback mode


See Also

Properties:

InsertSplit

Splits

Overviews:

Creating splits at design time using the layout editor

Introduction to TrueGrid splits

Overview of TrueGrid splits


See Also

Properties:

ColumnIndex

Columns

LeftColumn

Events:

ColumnChange

LeftColChange

Overviews:

Design time column layouts using the Layout Editor


See Also

Properties:

ColumnAtPoint

PointX

PointY

SplitAtPoint

Events:

DragCell

Overviews:

Dragging cells or rows from a grid to another control


See Also

Properties:

BottomRow

ReferenceRow

Rows

TopRow

Events:

RowChange

TopRowChange

Overviews:

Row numbers and what they mean


See Also

Properties:

BottomRow

ReferenceRow

RowIndex

TopRow

Events:

RowChange

TopRowChange

Overviews:

Row numbers and what they mean


See Also

Properties:

SelectedForeColor

Overviews:

TrueGrid color settings and font styles


See Also

Properties:

SelectedBackColor

Overviews:

TrueGrid color settings and font styles


See Also

Properties:

BookmarkCount

BookmarkList

SelectedBackColor

SelectedForeColor

Events:

MarkChange

QueryMark

Overviews:

Multiple selection overview

Using the BookmarkList to highlight query result rows


See Also

Properties:

Text

Overviews:

Data validation techniques

Overview of cell editing

TrueGrid live data updates and Validate handlers


See Also

Properties:

ColumnSetStatusAttr

ParamBackColor

ParamFontStyle

ParamForeColor

ParamStatus

Overviews:

Priority of Colors and Fonts Applied to Cells

How TrueGrid applies colors and fonts to a cell


See Also

Properties:

ColumnAtPoint

PointX

PointY

RowAtPoint

Events:

DragCell

Overviews:

Dragging cells or rows from a grid to another control


See Also

Properties:

Editable

EditActive

Events:

EnterEdit

ExitEdit

RequestEdit

Overviews:

Data validation techniques

Overview of cell editing

TrueGrid live data updates and Validate handlers


See Also

Properties:

SplitIndex

SplitPropsGlobal

Splits

Overviews:

Creating splits at design time using the layout editor

Introduction to TrueGrid splits

Overview of TrueGrid splits


See Also

Properties:

SplitGroup

SplitPropsGlobal

Splits

Ovewrview:

Creating splits at design time using the layout editor

Introduction to TrueGrid splits

Overview of TrueGrid splits


See Also

Properties:

Configurable

Overviews:

Giving the user control over splits

User interaction when splits are present


See Also

Properties:

SplitIndex

Overviews:

Creating splits at design time using the layout editor

Introduction to TrueGrid splits

Overview of TrueGrid splits


See Also

Properties:

InsertSplit

RemoveSplit

SplitGroup

SplitIndex

SplitPropsGlobal

SplitSize

SplitSizeMode

Events:

SplitChange

Overviews:

Creating splits at design time using the layout editor

Introduction to TrueGrid splits

Overview of TrueGrid splits


See Also

Properties:

SplitTabMode

WrapCellPointer

Overviews:

Mouse and keyboard interaction with splits


See Also

Properties:

Splits

SplitSizeMode

Overviews:

Creating splits at design time using the layout editor

Configuring the Size of Splits


See Also

Properties:

Splits

SplitSize

Overviews:

Creating splits at design time using the layout editor

Introduction to TrueGrid splits

Overview of TrueGrid splits


See Also

Properties:

AllowArrows

AllowTabs

SplitSelectable

WrapCellPointer

Overviews:

Mouse and keyboard interaction with splits


See Also

Properties:

AllowTabs

Overviews:

Mouse and keyboard interaction with splits


See Also

Properties:

ColumnText

Overviews:

Data validation techniques

Overview of cell editing

TrueGrid live data updates and Validate handlers


See Also

Properties:

BottomRow

ReferenceRow

RowIndex

Rows

Events:

RowChange

TopRowChange

Overviews:

Row numbers and what they mean


See Also

Properties:

HorzColor

VertLines

Overviews:

TrueGrid color settings and font styles


See Also

Properties:

HorzLines

VertColor

Overviews:

How to give the grid a 3-dimensional appearance


See Also

Properties:

HorzScrollbar


See Also

Properties:

About


See Also

Properties:

AllowArrows

AllowTabs

SplitSelectable

SplitTabMode

Overviews:

Mouse and keyboard interaction with splits


See Also

Overviews:

How TrueGrid reacts to Dynaset changes


See Also

Events:

ColumnChange

RowChange


See Also

Properties:

EditActive

Modified

Text

Events:

EnterEdit

ExitEdit

RequestEdit

Overviews:

Data validation techniques

Overview of cell editing

TrueGrid live data updates and Validate handlers


See Also

Properties:

ColumnIndex

Columns

Events:

CellChange

LeftColChange

RowChange

TopRowChange


See Also

Properties:

ColumnIndex

Columns

LeftColumn

RightColumn

Events:

CellChange

ColumnChange


See Also

Properties:

ReferenceRow

RowIndex

Rows

Events:

CellChange

ColumnChange

RowChange

TopRowChange


See Also

Properties:

BottomRow

RowIndex

Rows

TopRow

Events:

ColumnChange

RowChange


See Also

Properties:

EditActive

EditDropDown

Modified

Text

Events:

Change

ExitEdit

RequestEdit

Overviews:

Data validation techniques

Overview of cell editing


See Also

Properties:

EditActive

EditDropDown

Modified

Text

Events:

Change

EnterEdit

RequestEdit

Overviews:

Data validation techniques

Overview of cell editing


See Also

Properties:

EditActive

EditDropDown

Modified

Text

Events:

Change

EnterEdit

ExitEdit

Overviews:

Data validation techniques

Overview of cell editing


See Also

Properties:

Modified

Text

Events:

Change

Validate

Overviews:

Data validation techniques

Overview of cell editing

TrueGrid live data updates and Validate handlers


See Also

Properties:

Modified

Text

Events:

Change

Update

Overviews:

Data validation techniques

Overview of cell editing

TrueGrid live data updates and Validate handlers


See Also

Events:

Update

Overviews:

Introduction to TrueGrid Callback mode


See Also

Properties:

ColumnCellAttrs

Overviews:

Priority of Colors and Fonts Applied to Cells

How TrueGrid applies colors and fonts to a cell


See Also

Properties:

ColumnFetchMargins


Properties:

BookmarkCount

BookmarkList

SelectMode

Events:

QueryMark

Overviews:

Multiple selection overview

Using the BookmarkList to highlight query result rows


See Also

Properties:

BookmarkCount

BookmarkList

SelectMode

Events:

MarkChange

Overviews:

Multiple selection overview

Using the BookmarkList to highlight query result rows


See Also

Properties:

SplitIndex

Overviews:

Creating splits at design time using the layout editor

Introduction to TrueGrid splits

Overview of TrueGrid splits


See Also

Properties:

ColumnExpression

ColumnType

Overviews:

What are unbound and calculated columns?


See Also

Properties:

EditDropDown


See Also

Properties:

ColumnWidth


See Also

Properties:

ColumnComboMaxItems

VlistStyle

Events:

ClickButton


See Also

Properties:

VlistStyle


See Also

Properties:

ColumnSumEnable

Events:

ColumnSumChange

Overviews:

Using Column Summaries


See Also

Properties:

ColumnSum

Events:

ColumnSumChange

Overviews:

Using Column Summaries


See Also

Properties:

VlistCount

VlistData

VlistDefault

VlistPicture

VlistStyle

VlistText


See Also

Properties:

VlistColumn

VlistData

VlistPicture

VlistText


See Also

Properties:

VlistColumn

VlistCount

VlistPicture

VlistText


See Also

Properties:

VlistColumn

VlistCount

VlistPicture

VlistText


See Also

Properties:

VlistColumn

VlistCount

VlistDefault

VlistText


See Also

Properties:

ColumnButton

ColumnComboMaxItems

VlistDefault

VlistText


See Also

Properties:

VlistColumn

VlistCount

VlistDefault

VlistPicture


See Also

Properties:

ColumnButton

VlistStyle


See Also

Properties:

ColumnSum

ColumnSumEnable

Overviews:

Using Column Summaries


See Also

Overviews:

Using the CheckRows Event


 See Also

Properties:

SelectMode


See Also

Properties:

Layout


See Also

Properties:

VlistStyle


See Also

Properties:

ColumnVisible

ColumnStyle


See Also

Properties

InsertSplit

RemoveSplit

ColumnVisible

ColumnOrder

Layout

LayoutIndex


See Also

Properties

VlistStyle

ColumnButton

ColumnComboMaxItems


ClickButton event example

This example demonstrates how to use the Click button event to pop up another grid on top of a cell to simulate a drop-down list box on the grid.

Sub Form_Load ()

 This setting causes a button to appear in the current cell for

 column 2 when the user moves to that column

Table1.ColumnButton(2) = True

End Sub

Sub Table1_ClickButton ()

' Position the related data control to the proper row

Data2.Recordset.FindFirst "Au_ID = " & Table1.Text

 Popup the dropdown

Table2.Top = Table1.CellRectTop + Table1.CellRectHeight

Table2.Left = Table1.CellRectLeft

Table2.Visible = True

Table2.SetFocus

End Sub


ExposeCellMode property example

This examples changes the ExposeCellMode when the grid becomes read-only so that the grid does not shift accidentally when the user clicks in the rightmost cell.

' Set the grid to read-only

Table1.Editable = False

'Change the ExposeCellMode to 2 - Leave Cell Clipped

Table1.ExposeCellMode = 2

Note that you could also set ExposeCellMode to 1 in this case since there would be no case where the user could edit the cell but 2 is more accurate.


Active property example

Note that the grid automatically suppresses updates to the grid while your program code is executing. You rarely have to set the grid Active property.

Table1.Active = False	' Set grid to inactive

...

' In a modal dialog box: Perform a lot of record repositioning (e.g.,

' navigating through the entire Recordset to calculate a column total),

' or allow user to interactively navigate and change the Recordset but

' do not want the grid to respond until user is all done.

...

Table1.Active = True	' Restore the grid to active.  The

' grid will refresh automatically.


DataSourceHwnd property example

This example demonstrates binding a grid to a Data Control which is in a different form.  Assuming the Data1 is in Form1 and Table1 is in Form2.  Form1 is loaded first then Form2, when Form2 is loaded, Table1 will be bound to Data1 in Form1 via the SouceHwnd property.  (Caution: Do not deactivate Form1 while Form2 is active, this will cause unpredictable results.  As a precaution, set Form1 so that end-user cannot interactively unload the form)

' Form_load event for Form2.  Table1 in Form2 will be bound to Data1

' in Form1 in this routine via the DataSourceHwnd property.

Sub Form_Load ()

Data1Hwnd% = TgGetControlHwnd(Form1.Data1)	' Make sure you include

' TGCONST.TXT in your project

Table1.DataSourceHwnd = Data1Hwnd%

End Sub


Some grid and column color examples

This example demonstrates setting the cell colors of the grid to red on white, except for column 1 (all splits) and column 2 of Split 1 which will be black on yellow.

' Set column 1 of all splits to black on yellow

Table1.SplitPropsGlobal = True	' Apply to all splits

Table1.ColumnForeColor(1) = BLACK

Table1.ColumnBackColor(1) = YELLOW

' Set column 2 of split 1 to black on yellow

Table1.SplitPropsGlobal = False	' Apply to specified split

Table1.SplitIndex = 1	' Apply to Split 1

Table1.ColumnForeColor(2) = BLACK

Table1.ColumnBackColor(2) = YELLOW

' Set overall grid cell color to red over white

Table1.ForeColor = RED

Table1.BackColor = WHITE

Note that even the grid color is defined last, the column specific colors will override the overall grid color.  Also, SplitPropsGlobal does not apply to ForeColor and BackColor which are always applied globally to all grid cells.  See also attribute precedence.


Some split color example

This example demonstrates setting various split specific colors.  See also attribute precedence.

' Set all splits' Head colors to black over yellow.

Table1.SplitPropsGlobal = True	' Apply to all splits

Table1.HeadForeColor = BLACK

Table1.HeadBackColor = YELLOW

' Set split 1 Edit colors to white on red, Horz and Vert

' colors to blue

Table1.SplitPropsGlobal = False	' Apply to specified split

Table1.SplitIndex = 1	' Apply to split 1

Table1.EditForeColor = WHITE

Table1.EditBackColor = RED

Table1.HorzColor = BLUE

Table1.VertColor = BLUE

' Set Split 3 Inactive colors to white on black and selected

' colors to white on magenta

Table1.SplitIndex = 3	' Apply to split 3

Table1.InactiveForeColor = WHITE

Table1.InactiveBackColor = BLACK

Table1.SelectedForeColor = WHITE

Table1.SelectedBackColor = MAGENTA


Grid, split and column fonts example

This example demonstrates setting various font styles in TrueGrid.

' For Column 1 in all splits, set cells to italic and

' headings to bold+italic

Table1.SplitPropsGlobal = True	' Apply to all splits

Table1.ColumnFontStyle(1) = 3	' Italic

Table1.ColumnHeadFontStyle(1) = 4	' bold+Italic

' For Column 2 of Split 1, set cells to underline

' and heading to bold+underline

Table1.SplitPropsGlobal = False	' Apply to specified split

Table1.SplitIndex = 1	' Apply to Split 1

Table1.ColumnFontStyle(2) = 5	' Underline

Table1.ColumnHeadFontStyle(2) = 6	' bold+Underline

' Set all other cells to bold (Note that SplitPropsGlobal

' does not affect FontBold which always applies to all cells)

Table1.FontBold = True

' Set all other headings to bold

Table1.SplitPropsGlobal = True	' Apply to all splits

Table1.HeadFontStyle = 2	' bold

Note that even FontBold and HeadFontStyle are set last, the column properties will override the overall grid properties.  See also attribute precedence.


AddRegexAttr property example

This example demonstrates setting per-cell colors of specified splits according to cell contents.

' For all splits, set the color of cells containing

' negative numbers to red-bold.  But if the cell is

' current, uses red-italic.

Table1.SplitPropsGlobal = True	' Apply to all splits

Table1.ParamBackColor = -1	' Use grid BackColor

Table1.ParamFontStyle = 2	' Bold font style

Table1.ParamStatus = -1	' Apply to all cells

Table1.ParamForeColor = RED	' Set fore color to red

Table1.AddRegexAttr = "^-"	' Match 1 st character of

' cell with "-"

Table1.ParamFontStyle = 3	' Italic font style

Table1.ParamStatus = GFS_CURCELL	' Apply to current cell

Table1.AddRegexAttr = "^-"	' Match 1 st character of

' cell with "-"

Note that when setting ParamStatus to GFS_CURRENT above, it applies to cells whose status is GFS_CURRENT only.  For example., if a cell is GFS_CURRENT and is also GFS_CHANGED, then the red-italic color above does not apply.  This method gives programmers complete control over cell color based on cell contents and cell status.  To see how to apply a color to the current cell regardless of other status, see TgSetCurCellColor in TGUTILS.BAS

' For Split 1, display all "normal cells" containing "PA" in

' blue over yellow and in bold, and "NY" in black over yellow

' and in bold

Table1.SplitPropsGlobal = False	' Apply to specified split

Table1.SplitIndex = 1	' Apply to Split 1

Table1.ParamBackColor = YELLOW	' Set back color to yellow

Table1.ParamForeColor = BLUE	' Set fore color to blue

Table1.ParamFontStyle = 2	' Bold font style

Table1.ParamStatus = 0	' Apply to all "normal cells"

' (i.e., cells that doesn't have

' any of the 4 basic status.)

Table1.AddRegexAttr = "^PA$"	' Match cell contents with

' "PA".  For case sensitive

' match, use "^[P][A]$"

Table1.ParamForeColor = BLACK	' Set fore color to blue

Table1.AddRegexAttr = "^NY$"	' Match cell contents with

' "NY"

See also attribute precedence.


ColumnAddRegexAttr property example

This example demonstrates setting per-cell colors of specified columns and splits according to cell contents.

' For Column 5 of all splits, set the color of cells

' containing negative numbers to red-bold.  But if the

' cell is current, uses red-italic.

Table1.SplitPropsGlobal = True	' Apply to all splits

Table1.ParamBackColor = -1	' Use grid BackColor

Table1.ParamFontStyle = 2	' Bold font style

Table1.ParamStatus = -1	' Apply to all cells

Table1.ParamForeColor = RED	' Set fore color to red

Table1.ColumnAddRegexAttr(5) = "^-"	' Match 1 st character of

' cell with "-"

Table1.ParamFontStyle = 3	' Italic font style

Table1.ParamStatus = GFS_CURCELL	' Apply to current cell

Table1.ColumnAddRegexAttr(5) = "^-"	' Match 1 st character of

' cell with "-"

Note that when setting ParamStatus to GFS_CURRENT above, it applies to cells whose status is GFS_CURRENT only.  For example., if a cell is GFS_CURRENT and is also GFS_CHANGED, then the red-italic color above does not apply.  This method gives programmer complete control over cell color based on cell contents and cell status.  To see how to apply a color to the current cell regardless of other status, see TgSetCurCellColor in TGUTILS.BAS.

' For Column 5 of Split 1, display all "normal cells" containing

' "PA" in blue over yellow and in bold, and "NY" in black

' over yellow and in bold

Table1.SplitPropsGlobal = False	' Apply to specified split

Table1.SplitIndex = 1	' Apply to Split 1

Table1.ParamBackColor = YELLOW	' Set back color to yellow

Table1.ParamForeColor = BLUE	' Set fore color to blue

Table1.ParamFontStyle = 2	' Bold font style

Table1.ParamStatus = 0	' Apply to all "normal cells"

' (i.e., cells that doesn't have

' any of the 4 basic status.)

Table1.ColumnAddRegexAttr(5) = "^PA$"

' Match cell contents with

' "PA".  For case sensitive

' match, use "^[P][A]$"

Table1.ParamForeColor = BLACK	' Set fore color to blue

Table1.ColumnAddRegexAttr(5) = "^NY$"

' Match cell contents with

' "NY"

See also attribute precedence.


ColumnSetStatusAttr property example

This example demonstrates setting per-cell colors of specified columns and splits according to cell status.

' For Column 5 of all splits, set current cell color to

' red-italic, and updated cell color to blue-bold

Table1.SplitPropsGlobal = True	' Apply to all splits

Table1.ParamBackColor = -1	' Uses grid BackColor

Table1.ParamFontStyle = 3	' Uses italic font style

Table1.ParamForeColor = RED	' Uses red for fore color

Table1.ColumnSetStatusAttr(5) = GFS_CURCELL

' Apply to current cell

Table1.ParamFontStyle = 2	' Uses bold font style

Table1.ParamForeColor = BLUE	' Uses blue for fore color

Table1.ColumnSetStatusAttr(5) = GFS_CHANGED

' Apply to updated cells

Note that when setting ColumnSetStatusAttr to GFS_CHANGED above, it applies to cells whose status is GFS_CHANGED only.  For example., if a cell is GFS_CHANGED and is also GFS_CURCELL, then the blue-bold color above does not apply.  This method gives programmer complete control over cell color based on cell status.  For your convenience, TrueGrid comes with some useful routines (e.g., TgSetCurCellColor, TgSetMarqueeColor) in TGUTILS.BAS to help you control cell colors.

' For Column 5 of Split 1, set updated-current cell to red

' over blue

Table1.SplitPropsGlobal = False	' Apply to specified split

Table1.SplitIndex = 1	' Apply to Split 1

Table1.ParamBackColor = BLUE	' Uses blue for back color

Table1.ParamFontStyle = -1	' Uses grid font style

Table1.ParamForeColor = RED	' Uses red for fore color

Table1.ColumnSetStatusAttr(5) = GFS_CURCELL + GFS_CHANGED

' Apply if current cell is

' also updated

See also attribute precedence.


SetStatusAttr property example

This example demonstrates setting per-cell colors of specified splits according to cell status.

' For all splits, set current cell color to red-italic,

' and updated cell color to blue-bold

Table1.SplitPropsGlobal = True	' Apply to all splits

Table1.ParamBackColor = -1	' Uses grid BackColor

Table1.ParamFontStyle = 3	' Uses italic font style

Table1.ParamForeColor = RED	' Uses red for fore color

Table1.SetStatusAttr = GFS_CURCELL	' Apply to current cell

Table1.ParamFontStyle = 2	' Uses bold font style

Table1.ParamForeColor = BLUE	' Uses blue for fore color

Table1.SetStatusAttr = GFS_CHANGED	' Apply to updated cells

Note that when setting SetStatusAttr to GFS_CHANGED above, it applies to cells whose status is GFS_CHANGED only.  For example., if a cell is GFS_CHANGED and is also GFS_CURCELL, then the blue-bold color above does not apply.  This method gives programmer complete control over cell color based on cell status.  For your convenience, TrueGrid comes with some useful routines (e.g., TgSetCurCellColor, TgSetMarqueeColor) in TGUTILS.BAS to help you control cell colors.

' For Split 1, set updated-current cell to red over blue

Table1.SplitPropsGlobal = False	' Apply to specified split

Table1.SplitIndex = 1	' Apply to Split 1

Table1.ParamBackColor = BLUE	' Uses blue for back color

Table1.ParamFontStyle = -1	' Uses grid font style

Table1.ParamForeColor = RED	' Uses red for fore color

Table1.SetStatusAttr = GFS_CURCELL + GFS_CHANGED

' Apply if current cell is

' also updated

See also attribute precedence.


ColumnHasRegexAttr and HasRegexAttr properties example

This example demonstartes canceling contents-based attributes of a gird.

' Cancel all contents-based per-cell attributes for all splits

Table1.SplitPropsGlobal = True	' Apply to all splits

Table1.HasRegexAttr = False

' Cancel contents-based per-cell attributes for Column 5

' of Split 1

Table1.SplitPropsGlobal = False	' Apply to specified split

Table1.SplitIndex = 1	' Apply to Split 1

Table1.ColumnHasRegexAttr(5) = False


ColumnCellAttrs property and FetchAttributes event example

' Tell the grid to call the FetchAttributes

' event to get the asttributes for displaying the

' cell contents of Column 5 in Split 2

Table1.SplitPropsGlobal = False	' Apply to specified split

Table1.SplitIndex = 2	' Apply to Split 2

Table1.ColumnCellAttrs(5) = True

' Assuming Column 5 is a Salary field.  This FetchAttributes

' event instructs the grid to:

'	- Display all updated cells in red-bold-underline

'	- Use default attributes if Salary < 20000

'	- Use blue fore color if Salary < 50000

'	- Use red fore color if Salary < 100000

'	- Use red-bold if Salary >= 100000

Sub Table1_FetchAttributes (Status As Integer, Split As Integer, Row As Long, Col As Integer, FgColor As Long, BgColor As Long, FontStyle As Integer)

Dim Salary As Long

Salary = Val(Table1.ColumnText(5))

If Status And GFS_CHANGED Then

FgColor = RED

FontStyle = 6	' Bold+underline

ElseIf Salary >= 100000 Then

FgColor = RED

FontStyle = 2	' Bold

ElseIf Salary >= 50000 Then

FgColor = RED

ElseIf Salary >= 20000 Then

FgColor = BLUE

End If

End Sub

Note that in the above example, the cell will be painted red-bold-underline if Status "contains" the GFS_CHANGED status (e.g., if Status is current and changed).  To display in red-bold-underline for "changed" status only, use:

If Status = GFS_CHANGED Then

FgColor = RED

FontStyle = 6	' Bold+underline

ElseIf Salary >= 100000 Then

...


ColumnFetchMargins property and FetchMargins event example

' Tell the grid to call the FetchMargins

' event to determine the indentation when displaying the

' cell contents of Column 1 and Column 2 for all splits

Table1.SplitPropsGlobal = True	' Apply to all splits

Table1.ColumnFetchMargins(1) = True

Table1.ColumnFetchMargins(2) = True

' Assuming Column 1 is company name or branch office name.

' Column 2 is a numeric company code.  A company code containing

' a decimal indicates Column 1 is a branch office.  This

' FetchMargins event displays all branch office

' name and code indented.

Sub Table1_FetchMargins (Split As Integer, Row As Long, Col As Integer, InsetLeft As Integer, InsetRight As Integer)

If InStr(Table1.ColumnText(2), ".") <> 0 Then

' Indent Column 1 two characters, Column 2 four characters

InsetLeft = Iif(Col = 1, 20, 40)

End If

End Sub


Some heading properties example

This example demonstrates setting heading properties.  See also Split color example

' Set all splits' HeadFontStyle to bold

Table1.SplitPropsGlobal = True	' Apply to all splits

Table1.HeadFontStyle = 2	' Bold

' No headings for split 2

Table1.SplitPropsGlobal = False	' Apply to specified split

Table1.SplitIndex = 2	' Apply to Split 2

Table1.Headings = False	' No heading

' Set heading height.  Note that this property applies to all

' splits in the entire grid.and is not affected by SplitPropsGlobal.

Table1.HeadingHeight = 2.5	' 2.5 characters high


HorzLines, HorzColor, VertLines, and VertColor properties example

This example demonstrates setting the grid to a 3D look.

Table1.HorzLines = 2	' 3D horizontal lines

Table1.VertLines = 2	' 3D vertical lines

Table1.HorzColor = &H00808080&	' Grid horizontal lines to dark grey

Table1.VertColor = &H00808080&	' Grid vertical lines to dark grey

Table1.BackColor = &H00C0C0C0&	' Grid back color to medium grey


Layout property example

This example demonstrates saving the current grid layout to a binary file and then restoring it later.

Dim LayoutVar as Variant

'Allows you to save a layout to a binary file

LayoutVar = Table1.Layout

Open "Layout.txt" For Binary As #1

Put #1, , LayoutVar

Close #1

'Reads the binary file and sets the new layout

Open "Layout.txt" For Binary As #1

Get #1, , LayoutVar

Table1.Layout = LayoutVar

Close #1


Marquee properties example

This example sets the Marquee properties.

Table1.MarqueeStyle = 4	' Highlight Row & Cell

Table1.MarqueeUnique = False	' Marquee cell appears in all

' splits

See aslo the TgSetMarqueeColor routine in TGUTILS.BAS in your TrueGrid installation directory.  It is a routine to help you set the Marquee color.


Some row and column properties example

This example assumes the DataMode property of the grid is set to 1 - callback mode.  The grid is used to display 5 columns and 10 rows of data.

Table1.LinesPerRow = 2	' 2 lines per row

Table1.Columns = 5	' Declare 5 columns of data

Table1.Rows = 20	' Declare 20 rows of data

Table1.TopRow = 6	' Initialize top row to be the

' 6 th data row

Table1.LeftColumn = 2	' Initialize left column to be

' the 2 nd column

Table1.RowIndex = 7	' Initialize the current cell to

Table1.ColumnIndex = 4	' the 2 nd row from the top, and 3 rd

' column from the left

VisibleRows = Table1.BottomRow - Table1.TopRow + 1

' Calculates number of visible rows

MoveLeft = Table1.LeftColumn + 1

MoveRight = Table1.RightColumn + 1	' Works only if Columns are

' in sequential order

' Calculates number of visible columns

' Set ColumnName

Table1.ColumnName(1) = "Company Name"

Table1.ColumnName(2) = "Co. Code"

Table1.ColumnName(3) = "Co. Contact"

Table1.ColumnName(4) = "Phone"

Table1.ColumnName(5) = "Address"

' Set ColumnWidth (column display width in characters) and ColumnSize

' (maximum number of characters that can be entered by user at the

' specified column).

Table1.ColumnWidth(1) = 20

Table1.ColumnSize(1) = 16

Table1.ColumnWidth(2) = 10

Table1.ColumnSize(2) = 8

Table1.ColumnWidth(3) = 12

Table1.ColumnSize(3) = 10

Table1.ColumnWidth(4) = 14

Table1.ColumnSize(4) = 12

Table1.ColumnWidth(5) = 24

Table1.ColumnSize(5) = 20


ColumnField, ColumnType and ColumnExpression properties example

The properties in this example can very easily be defined using the Layout Editor at design time.  This example demonstrates how the same properties can be defined or modified in code.

Assuming a database with the following five (5) fields:  last name,  first name,  invoice_date,  amount_due,  interest_rate.  You can use one of the following 2 methods to setup the column layout by code in the Form_Load event:

1.	First define a "blank layout" for the grid at design time: when the Layout Editor first popup at design time, answer "No" when asked "Use database layout from DataSource?"  Then quit the Layout Editor without defining any columns.  Once the Layout Editor is invoked, the database layout of the Data Control will not be used to initialize the grid at run time (even the layout is blank).  You can then use code to define or override the layout anytime you want.  If you use this method, you can skip the "Data1.Refresh" and "DoEvents" commands in the Form_Load event below.

2.	Do not invoke the Layout Editor at design time and let the grid initialize itself at run time.  The "Data1.Refresh" and "DoEvents" commands in the Form_Load event below will initialize the grid using the database layout of the Data Control.  Once the grid has been initialized, you can then use code to override the current grid layout.  Note that if you do not use "Data1.Refresh" to first initialize the grid, the grid will be initialized after the Form_Load event and will override all the grid layout defined in the Form_load event.

Sub Form_Load ()

Data1.Refresh	' Force the grid to initialize

DoEvents

Table1.Columns = 0	' Cancel current layout to start

' from fresh

'The grid will be used to display 6 columns:

Table1.ColumnType(1) = 2	' Calculated

Table1.ColumnType(2) = 0	' Bound

Table1.ColumnType(3) = 0	' Bound

Table1.ColumnType(4) = 0	' Bound

Table1.ColumnType(5) = 2	' Calculated

Table1.ColumnType(6) = 2	' Calculated

' The invoice_date, amount_due and interest_rate fields are

' displayed in columns  2, 3, 4 of the grid, respectively:

Table1.ColumnField(2) = "invoice_date"

Table1.ColumnName(2) = "Invoice Date"

Table1.ColumnField(3) = "amount_due"

Table1.ColumnName(3) = "Amount Due"

Table1.ColumnField(4) = "interest_rate"

Table1.ColumnName(4) = "Interest Rate"

' Column 1 is a calculated column (ColumnType equals to 2)

' displaying the concatenation of the first name and last

' name fields (with a space between them).

' The ColumnExpression property is:

Table1.ColumnName(1) = "Name"

Table1.ColumnExpression(1) = "[first name] & Space$(1) & [last name]"

' Note that the first name and last name fields can be used

' in the expression even though they are not displayed in the

' grid.

' Column 5 is another calculated column which calculates the

' number of days the invoice is overdue:

Table1.ColumnName(5) = "OverDue Day"

dStr$ = Chr$(34) + "d" + Chr$(34)

Table1.ColumnExpression(5) = "DateDiff(" + dStr$ + ", invoice_date, Now)"

' Column 6 calculates the total amount due, assuming the

' interest_rate is a daily rate:

Table1.ColumnName(6) = "Total Due"

Table1.ColumnExpression(6) = "amount_due + interest_rate * Val(ColumnText(5))"

' Note that Column 6 is dependent on Column 5.  TrueGrid will

' automatically calculate Column 5 first before calculating Column 6.

End Sub


ColumnOrder property example

The grid contains five columns: NAME, ADDRESS, CITY, STATE, ZIP.  The user drags the STATE column to the first column position.  The ColumnOrder array now looks like this:

Table1.ColumnOrder(1) = 2  	' NAME

Table1.ColumnOrder(2) = 3  	' ADDRESS

Table1.ColumnOrder(3) = 4  	' CITY

Table1.ColumnOrder(4) = 1  	' STATE

Table1.ColumnOrder(5) = 5  	' ZIP

To achieve the same result in code, you would have to execute the first four of these assignment statements.  By itself, the statement

Table1.ColumnOrder(4) = 1

merely exchanges the NAME and STATE columns.


Miscellaneous Column properties example

Assuming the grid has 2 splits and the database has 5 fields (lastname, firstname, birthday, address and salary).

' Set ColumnName, ColumnWidth, ColumnStyle and EditMask for all splits:

Table1.SplitPropsGlobal = True	' Apply to all splits

Table1.ColumnName(1) = "Last Name"

Table1.ColumnName(2) = "First Name"

Table1.ColumnName(3) = "Birthday"

Table1.ColumnName(4) = "Address"

Table1.ColumnName(5) = "Salary"

Table1.ColumnWidth(1) = 20	' 20 characters

Table1.ColumnWidth(2) = 20	' 20 characters

Table1.ColumnWidth(3) = 15	' 15 characters

Table1.ColumnWidth(4) = 50	' 50 characters

Table1.ColumnWidth(5) = 10	' 10 characters

Table1.ColumnStyle(1) = GRS_CENTER + GRS_HSAME	' Center cells & heading

Table1.ColumnStyle(2) = GRS_CENTER + GRS_HSAME	' Center cells & heading

Table1.ColumnStyle(3) = GRS_CENTER + GRS_HSAME	' Center cells & heading

Table1.ColumnStyle(4) = GRS_LEFT + GRS_HCENTER	' Cells-LJ, heading-center

Table1.ColumnStyle(5) = GRS_LEFT + GRS_HCENTER	' Cells-LJ, heading-center

Table1.EditMask(3) = "General Date"

Table1.EditMask(5) = "Currency"

' Set ColumnVisible for different splits

Table1.SplitPropsGlobal = False	' Apply to specified splits

Table1.SplitIndex = 1	' Apply to Split 1

Table1.ColumnVisible(3) = False	' Column 3 invisible

Table1.ColumnVisible(4) = False	' Column 4 invisible

Table1.ColumnVisible(5) = False	' Column 5 invisible

Table1.SplitIndex = 2	' Apply to Split 2

Table1.ColumnVisible(1) = False	' Column 1 invisible

Table1.ColumnVisible(2) = False	' Column 2 invisible


Scrollbar properties example

' Set scrollbar properties for Splits 1 and 2

Table1.SplitPropsGlobal = False	' Apply to specified splits

Table1.SplitIndex = 1	' Apply to Split 1

Table1.HorzScrollbar = 0	' No horizontal scrollbar

Table1.VertScrollbar = 2	' Automatic vertical scrollbar

Table1.SplitIndex = 2	' Apply to Split 2

Table1.HorzScrollbar = 2	' Automatic horizontal scrollbar

Table1.VertScrollbar = 1	' Always have vertical scrollbar


Keyboard and mouse navigation properties example

This example demonstrates controlling keyboard and mouse navigation, and selectability within a grid.

' Set up key navigation properties.  These properties are global

' (i.e., independent of the SplitPropsGlobal property)

Table1.TabCapture = True	' Tab will not exit the grid

Table1.SplitTabMode = 1	' Navigation keys will move across splits

Table1.AllowArrows = True	' Arrow key will move from cell to cell

Table1.AllowTabs = True	' Tab will move from cell to cell

Table1.WrapCellPointer = True	' Arrow key will wrap to next (previous) row

' Assuming there are 3 splits, the code below sets Split 2 to be

' "non-selectable."  For example., navigation keys will move across Splits

' 1 and 2, but will skip or jump over Split 2.  Also, users will not

' be able to focus on Split 2 by clicking the cells or headings

' within in the split.

Table1.SplitPropsGlobal = False	' Apply to specified split

Table1.SplitIndex = 2	' Apply to Split 2

Table1.SplitSelectable = False	' Split 2 is not selectable


Configurability properties example

This examples sets Split 2 to be non-configurable and locked.

Table1.SplitPropsGlobal = False	' Apply to specified split

Table1.SplitIndex = 2	' Apply to Split 2

Table1.Configurable = False	' User cannot re-size or

' re-order columns

Table1.SplitLocked = True	' User cannot split Split 2

See also the routines TgLockColumnLeft and TgLockColumnRight in TGUTILS.BAS in your TrueGrid installation directory.


ColumnChanged and ColumnText properties example
ColumnChanged properties example

This example demonstrates using the ColumnChanged property in the Data Control Validate event to check if additional calculation is required:

Sub Data1_Validate (Action As Integer, Save As Integer)

' Assuming Column 5 displays the "Sales" field

If Table1.ColumnChanged(5) Then

' Update sum of sales for all records which is

' displayed in a text control Text1

Text1.text = Str$(Val(Text1.text) + Val(Table1.ColumnText(5))

- Data1.Recordset.Fields("Sales"))

End If

End Sub


SplitEditable property example

This example demonstrates making split number 2 not editable while preserving the current split index.

SaveIndex = Table1.SplitIndex	' Save current SplitIndex

Table1.SplitPropsGlobal = False	' Apply to specified split

Table1.SplitIndex = 2	' Set SplitIndex to 2

Table1.SplitEditable = False	' Turn off edit

Table1.SplitIndex = SaveIndex	' Restore SplitIndex


Some editing properties example

This example demonstrates using a check box and the grid's KeyPress event to control editing.

' Assume the form has a check box (Check1) for user to toggle if

' the grid is editable.

Sub Check1_Click ()

Table1.Editable = Check1.Value

End Sub

' This program lets the user to use the space key to cancel all current editing. (the Escape key does this by default, this example illustrates how to assign another key to perform the same function.)

Sub Table1_KeyPress (KeyAscii As Integer)

If KeyAscii = 32 Then

Table1.Modified = False	' Nullify user's editing

Table1.EditActive = False	' Exit edit mode

End If

End Sub


RequestEdit event example

This example demonstrates using the RequestEdit event for user to enter or edit a single character field without entering into edit mode.

' For the column with ColumnName = "Paid?", user is allowed to press

' only "Y", "y", "N" or"n".

Sub Table1_RequestEdit (Cancel As Integer, KeyAscii As Integer)

If Table1.ColumnName(Table1.ColumnIndex) = "Paid?" Then

Cancel = True	' Do not enter edit mode

If UCase$(Chr$(KeyAscii)) = "Y" Then

    Table1.ColumnText(Table1.ColumnIndex) = "Yes"

ElseIf UCase$(Chr$(KeyAscii)) = "N" Then

    Table1.ColumnText(Table1.ColumnIndex) = "No"

Else

    Beep

End If

End If

End Sub


EditDropDown property example

' Set EditDropDown to False so that there is no DropDown for editing.

' Instead, text will scroll within the grid cell if there is more text

' than the cell width can display.

Table1.EditDropDown = False


FetchMode property example

' Wait till all data is fetched before dispalying them at

' the same time to the grid

Table1.FetchMode = 2


DataChanged property and Update event example

This example demonstrates using the DataChanged property in the grid Update event to nullify all data edited by user.in all columns (not just the current column)

Sub Table1_Update (Row As Long, Col As Integer, Value As String)

If Val(Table1.ColumnText(5)) <= 1000 Then

Table1.DataChanged = False	' Nullify all user changes in

' al columns

Beep

End If

End Sub


Append event example

This example demonstrates using the Append event to add a new record if user presses the down arrow key at the bottom of the grid.  This example also puts a default value in Column one.  The DoEvents allows the grid to respond to the Data Control AddNew.

Sub Table1_Append ()

If MsgBox("Add new record?", 1) = 2 Then Exit Sub

Data1.Recordset.AddNew

DoEvents

Table1.ColumnText(1) = Default

End Sub


SelectMode, BookmarkCount and BookmarkList properties example

Allow record selection for all splits.

Table1.SplitPropsGlobal = True	' Apply to all splits

Table1.SelectMode = 1	' Mark and select record allowed

First clear all existing selected (marked) records by setting BookmarkCount to zero.

Table1.BookmarkCount = 0	' Clears all selected records

Select and mark all records with the Profit field value greater than $10,000.

' Clone current dynaset so that current dynaset will

' be preserved

Dim dClone As Dynaset

Set dClone = Data1.Recordset.Clone()

' Find and mark all records with Profit > 10000 using the clone

dClone.FindFirst "Profit > 10000"

While Not dClone.NoMatch

Table1.BookmarkList(Table1.BookmarkCount) = dClone.Bookmark

dClone.FindNext "Profit > 10000"

Wend

' To remove a particular bookmark (knowing the index), simply

' assign the MookmarkList to an empty string.

Table1.BookMarkList(2) = ""	' To remove the 3 rd bookmark


MarkChange and QueryMark events example

In callback mode, the programmer maintains his own "bookmark" list for selected records.  This example demonstrates how the MarkChange and QueryMark events are used to toggle the "bookmark" list.

' Assuming 50 rows of data, and programmer uses an array "Marked"

' to manage selected rows.  If a row is selected, Marked(row) is

' True, else it is False.

Dim Marked(1 to 50) As Integer

...

...

Sub Table1_MarkChange (Row As Long, IsMarked As Integer)

Marked(Row) = Marked(Row) Xor True	' Toggle between True/False

Table1.RefreshRow = Row	' Refresh Row so that the

' row will be properly

' highlighted (or un-highlighted)

End Sub

Sub Table1_QueryMark (Row As Long, IsMarked As Integer)

IsMarked = Marked(Row)

End Sub


Some split properties example

This example demonstrates creating splits and setting various split properties.

' Create 4 additional splits for the grid

Table1.Splits = 2

Table1.Splits = 3

Table1.Splits = 4

Table1.Splits = 5

' Make Splits 1 and 5 the same group; Splits 2, 3, 4 another Group.

' Split 1 always shows 1 column, Split 5 always shows 2 columns.

' Splits 2 and 3 are the same size and Split 4 is twice the size

' of Split 2 or 3.

Table1.SplitPropsGlobal = False	' Apply to specified split

Table1.SplitIndex = 1	' Apply to Split 1

Table1.SplitGroup = 1	' Assign Split to Group 1

Table1.SplitSizeMode = 2	' Split size is in columns

Table1.SplitSize = 1	' Split always displays 1 column

Table1.SplitIndex = 2	' Apply to Split 2

Table1.SplitGroup = 2	' Assign Split to Group 2

Table1.SplitSizeMode = 0	' Split size is scalable

Table1.SplitSize = 1	' Split size is 1 unit

Table1.SplitIndex = 3	' Apply to Split 3

Table1.SplitGroup = 2	' Assign Split to Group 2

Table1.SplitSizeMode = 0	' Split size is scalable

Table1.SplitSize = 1	' Split size is 1 unit

Table1.SplitIndex = 4	' Apply to Split 4

Table1.SplitGroup = 2	' Assign Split to Group 2

Table1.SplitSizeMode = 0	' Split size is scalable

Table1.SplitSize = 2	' Split size is 2 unit

Table1.SplitIndex = 5	' Apply to Split 5

Table1.SplitGroup = 1	' Assign Split to Group 1

Table1.SplitSizeMode = 2	' Split size is in columns

Table1.SplitSize = 2	' Split always displays 2 column

The split size deserves further explanations.  Assuming the grid is 10 inches wide.  After displaying 1 column in Split 1 and 2 columns in Split 5, let's say there are 8 inches total left in the grid for Splits 2, 3, and 4.  Splits 2 and 3 have a SplitSize of 1 unit and each will be 2 inches wide.  Split 4 has a SplitSize of 2 units and will be 4 inches wide.  Now suppose Splits 1 and 5 have scrolled and are displaying wider columns (they always display the same number of full columns as specified by SplitSize) and have taken up 6 inches of the grid.  There are now only 4 inches total for Splits 2, 3, and 4.  Following the same ratios, Splits 2 and 3 will be 1 inch each, and Split 4 will be 2 inches.

' Insert new splits to the right of Split 1 and Split 5

Table1.InsertSplit = 1	' Insert to right of Split 1

' The new split is now Split 1

Table1.InsertSplit = 6	' Insert to right of Split 6

' (formerly Split 5).  The new

' split is Split 7

' Remove Split 6 (formerly Split 5)

Table1.RemoveSplit = 6	' Split 7 now becomes Split 6


SplitChange event example

This example uses the SplitChange event to display the current SplitIndex in a label (Label1) and also generates a beep when switching from one split to another.

Sub Table1_SplitChange ()

Beep

Label1.Caption = "Current split is" & Str$(Table1.SplitIndex)

End Sub


Drag and drop example

This example demonstrates dragging a cell content from a grid (Table1) and dropping it on a cell of another grid (Table2).  (Note: make sure the DragIcon property of Table1 is set to some icon of your choice.  The default value will cause the entire grid to be dragged.)

' Table1_DragCell begins dragging the cell the user points to.

' Since the user may not start dragging with the current cell,

' this routine makes the "drag cell" current.

Sub Table1_DragCell (Split As Integer, Row As Long, Col As Integer)

Table1.RowIndex = Row	' Make drag cell current

Table1.ColumnIndex = Col

Table1.Drag 1	' Start drag

End Sub

' Assming Table2 uses MarqueeStyle = 4 (highlight row and cell),

' In order to give user adequate feedback, Table2_DragOver changes

' the MarqueeStyle to 2 (cell highlight) while the cell from Table1

' is being dragged over Table2 (except when dragged over Split 2 where

' "drop" is not allowed).

Sub Table2_DragOver (Source As Control, X As Single, Y As Single, state As Integer)

If state = 1 Then	' Leaving Table2

Table2.MarqueeStyle = 4 	' Restore highlight row & cell

Else

' Set current cell to the one we're pointing at

Table2.PointX = X

Table2.PointY = Y

If Table2.SplitAtPoint = 2 Then

    Table2.MarqueeStyle = 5	' Turn off marquee to signal

' "drop" is not allowed

Else

    Table2.MarqueeStyle = 2	' Hightlight current cell

End If

If Table2.RowAtPoint > 0 Then Table2.RowIndex = Table2.RowAtPoint

If Table2.ColumnAtPoint > 0 Then Table2.ColumnIndex = Table2.ColumnAtPoint

End If

End Sub

' Table2_DragDrop takes the cell data from Table1 and drops it

' into the current cell (dropping in Split 2 is not allowed).

Sub Table2_DragDrop (Source As Control, X As Single, Y As Single)

Table2.PointX = X

Table2.PointY = Y

If Table2.SplitAtPoint <> 2 Then

Table2.ColumnText(Table2.ColumnIndex) = Table1.Text

Data2.Recordset.Update

End If

Table2.MarqueeStyle = 4	' Restore MarqueeStyle after "drop"

End Sub


Drop down example

This example demonstrates using TrueGrid properties and events to implement a drop down list box when editing cells of a specified column.  In this example, Form1 contains a grid displaying a job schedule database.  The database contains a Status field.  When editing the Status field in the grid, a Visual Basic list box (List1) can optionally drop down to allow the user to pick a value from a pre-defined list.

' The "Status" in List1 are defined in the Form1_load event

Sub Form1_Load ()

List1.AddItem "Cancel"

List1.AddItem "Reschedule"

List1.AddItem "Pending"

List1.AddItem "Satisfactory"

List1.AddItem "Unacceptable"

List1.AddItem "In Progress"

List1.AddItem "Not Started"

End Sub

' The Table1_RequestEdit event optionally drop down List1 when

' user is editing the Status field

Sub Table1_RequestEdit (Cancel As Integer, KeyAscii As Integer)

If Table1.ColumnName(Table1.ColumnIndex) <> "Status" Then Exit Sub

' For the "Status" column, pop up a list box if user clicks

' (or double click) on the cell to request editing.  If user

' just started typing, then let user edit the text in the cell

' normally.

If KeyAscii Then Exit Sub 	' user just starts typing

' Pop up List1 (which is normally invisible) and align with

' current cell.

Cancel = True	' Cancel normal in-cell editing

List1.Top = Table1.CellRectTop + Table1.CellRectHeight

List1.Left = Table1.CellRectLeft

List1.Visible = True

List1.SetFocus

' If you want the right edge of List1 to align with the cell:

' List1.Left = Table1.CellRectLeft + Table1.CellRectWidth - List1.Width

' You can also use ColumnRectLeft to align List1:

' List1.Left = Table1.ColumnRectLeft

' List1.Left = Table1.ColumnRectLeft + Table1.ColumnRectWidth - List1.Width

End Sub

' When List1 got focus, try to set the index so that the item text

' is the same as that in the grid cell.

Sub List1_GotFocus ()

Dim i As Integer

For i = 0 To List1.ListCount - 1

If UCase(List1.List(i)) = UCase(Table1.Text) Then

    List1.ListIndex = i

    Exit Sub

End If

Next i

End Sub

' If user double clicks on List1, store the item to the grid cell

' and put away List1

Sub List1_DblClick ()

Table1.ColumnText(Table1.ColumnIndex) = List1.List(List1.ListIndex)

List1.Visible = False

End Sub

' Just get rid of List1 whenever it loses focus

Sub List1_LostFocus ()

List1.Visible = False

End Sub


CurCellVisible property example

This example demonstrates using a command button (Command1) to bring the current cell into the visible range of the grid.

Sub Command1_Click ()

Table1.CurCellVisible = True

End Sub


Version property example

This example displays the TrueGrid internal version number in a label (Label1).

Label1.Caption = "TrueGrid Version: " + Str$(Table1.Version)


A calback example
A callback example

In this example, the grid is in callback mode and the programmer stores the data in an array.

' The programmer collects data from COM 1 and stores them in an

' array variable Signal.  He then displays the data in a grid.

' The following code initializes the grid (with DataMode

 assigned to 1 - application mode at design time).

Dim Signal (1 to 3, 1 to 100)	' Declare Signal array

' Initialize the grid (e.g., in the Form_Load() event)

Table1.ColumnName(1) = "Signal 1"

Table1.ColumnName(2) = "Signal 2"

Table1.ColumnName(3) = "Signal 3"

Table1.ColumnWidth(1) = 14

Table1.ColumnWidth(2) = 14

Table1.ColumnWidth(3) = 14

Table1.ColumnSize(1) = 10

Table1.ColumnSize(2) = 10

Table1.ColumnSize(3) = 10

Table1.Rows = 100	' Declare 100 data rows for the grid

' The Table1_Fetch event is used to feed the grid with data

' to display

Sub Table1_Fetch (Row As Long, Col As Integer, Value As String)

Value = Signal(Col, Row)

End Sub

' The Table1_Update event is used to update the Signal data

' after user has updated the data in the grid

Sub Table1_Update (Row As Long, Col As Integer, Value As String)

Signal(Col, Row) = Value

End Sub

' If new Signal is recieved and stored in the Signal array

' variable, the grid does not know new data has arrived.  The

' program has to inform the grid to refresh with new data

' Assuming Rows 10, 11 and Column 2 are populated with new

' data, the grid is refreshed using the RefreshRow and Column

' methods.

Table1.RefreshRow = 10

Table1.RefreshRow = 11

Table1.RefreshColumn = 2


SplitPropsGlobal property example

This example demonstrates setting the grid HeadFontStyle for all splits and then setting the ColumnVisible property for individual splits.

Table1.SplitPropsGlobal = True	' Apply to all splits

Table1.HeadFontStyle = 4	' Set to bold-italic

Table1.SplitPropsGlobal = False	' Apply to current split

Table1.SplitIndex = 1	' Apply to Split 1

Table1 ColumnVisible(3) = False	' Make column 3 invisible

Table1.ColumnVisible(4) = False	' Make column 4 invisible

Table1.SplitIndex = 2	' Apply to Split 2

Table1 ColumnVisible(1) = False	' Make column 1 invisible

Table1.ColumnVisible(2) = False	' Make column 2 invisible


SplitLocked property example

This example demonstrates locking Columns 1 and 4 of a grid to the left edge of the grid.  Assuming the grid has 5 columns total and currently has only 1 split.

' First create a split for the locked columns

Table1.InsertSplit = 1

' Make all columns in Split 1 invisible except for

' Columns 1 and 4

Table1.SplitPropsGlobal = False	' Apply to current split

Table1.SplitIndex = 1	' Apply to Split 1

Table1.ColumnVisible(2) = False	' Make column invisible

Table1.ColumnVisible(3) = False	' Make column invisible

Table1.ColumnVisible(5) = False	' Make column invisible

' Set Split size and locked modes

Table1.SplitSizeMode = GSPT_COLUMNS	' Split size expressed in columns

Table1.SplitSize = 2	' 2 columns wide for Split 1

Table1.SplitLocked = True	' Lock the split

' Eliminate horizontal scrollbar.  This is actually not

' necessary if Columns 1 and 4 are the only columns in

' the split.

Table1.HorzScrollbar = 0

' Now make Columns 1 and 4 invisible in Split 2

Table1.SplitPropsGlobal = False	' Apply to current split

Table1.SplitIndex = 2	' Apply to Split 2

Table1.ColumnVisible(1) = False	' Make column invisible

Table1.ColumnVisible(4) = False	' Make column invisible

See also routines TgLockColumnLeft and TgLockColumnRight in TGUTILS.BAS in your TrueGrid installation directory.


ColumnChange, EnterEdit and ExitEdit events example

This example demonstrates using the ColumnChange, EnterEdit and ExitEdit events to display context sensitive help for users to edit data in the grid.  (The help text is displayed in a label - Label1.)  Assuming there are only 2 fields: Company Code and Company Name:

Sub Table1_ColumnChange ()

Select Case Table1.ColumnIndex

Case 1

    Label1.Caption = "This is company code"

Case 2:

    Label1.Caption = "This is company name"

End Select

End Sub

Sub Table1_EnterEdit ()

Select Case Table1.ColumnIndex

Case 1

    Label1.Caption = "Enter 4 digit company code"

Case 2:

    Label1.Caption = "Enter company name, 20 characters max."

End Select

End Sub

Sub Table1_ExitEdit ()

Call Table1_ColumnChange

End Sub


Validate event example

This example uses the Validate event to validate the data entered by the user in Columns 1 and 5 of the grid, and rejects the entry if the data is invalid.

Sub Table1_Validate(Row As Long, Col As Integer, Value As String, Cancel As Integer)

Select Case Col

Case 1

    ' Number entered in Column 1 must be less than or equal to 1000

    If Val(Value) > 1000 Then

        Beep

        Cancel = True

    End If

Case 5

    ' Column 5 must be "Y", "y", "N" or "n"

    If UCase$(Value) <> "Y" And UCase$(Value) <> "N" Then

        Beep

        Cancel = True

    End If

End Select

End Sub


ReferenceRow property example

Thisexample demonstrates using the ReferenceRow property to examine the visible column text on the screen without moving RowIndex or the record poistion of the Data Control.

SaveRef& = Table1.ReferenceRow	' Always save current ReferenceRow

For Row& = Table1.TopRow to Table1.BottomRow

Table1.ReferenceRow = Row&	' Position ReferenceRow to Row&

MsgBox (Table1.ColumnText(1))	' Examine text in Column 1

Next Row&

Table1.ReferenceRow = SaveRef&	' Always restore ReferenceRow


UnboundFetch event examples

If the ColumnType property is set to 1 - unbound, the UnboundFetch event is called by the grid to request data from the programmer for display.  In general, the database record may not be positioned to the "Row" argument of the UnboundFetch event.  If the programmer wishes to display data which is dependent on a database field, this example demonstrates using the "BookMark" argument to retrieve data in row "Row" of the database from the Recordset.

Sub Table1_UnboundFetch (Row As Long, Col As Integer, BookMark As String, Value As String)

curbm$ = Data1.Recordset.Bookmark	' Save current bookmark

Data1.Recordset.Bookmark = BookMark	' Position Recordset to BookMark

' Compute Value = "Quantity" * "Price" for the grid to display

Value = Data1.Recordset("Quantity") * Data1.Recordset("Price")

Data1.Recordset.Bookmark = curbm$	' Restore original bookmark

End Sub

Notice that the current Bookmark must be saved and restored.  The above event will NOT work properly, however, if the current row has been updated.  Moving the Bookmark causes an update to occur.  But the grid ignores any database activity during the UnboundFetch event and will not be properly notified of the update.  An alternative solution is to use a clone of the Recordset (since bookmarks are compatible), move to the Row in the clone and then get the data for the Row.

On the other hand, the ColumnText property always reflects the column text value in the "Row" argument of the UnboundFetch event.  This second example uses ColumnText to calculate values for the grid to display.

Sub Table1_UnboundFetch (Row As Long, Col As Integer, BookMark As String, Value As String)

' Assuming Column 2 is the "Quantity" field and Column 5

' is the "Price" field

Value = Val(Table1.ColumnText(2)) * Val(Table1.ColumnText(5))

End Sub


ColumnVertScroll property example

This example checks the field type of each database column to see if it is a memo field and turns off the ColumnVertScroll property (by default ColumnVertScoll is set to 2 - Automatic for these fields).

For i% = 0 To Table1.Columns - 1

If Data1.Database.TableDefs("Authors").Fields(Table1.ColumnField(i%)).Type = DB_MEMO Then

Table1.ColumnVertScroll(i%) = 0	'Never use scrollbar

End If

Next i%


ExtendRightCol property example

ExtendRightCol default is true.  In this example if there is more than one split we want the last split not to extend to the end of the grid.

If Table1.Splits > 1 Then

Table1.SplitIndex = Table1.Splits

Table1.ExtendRightCol = False

End If


Value list example

This example uses the value list properties to set up two types of value lists at run time.  Remember that you could also do this at design time.

' Set up value list for column 2

Table1.VlistColumn = 2

' Define value list as a dropdown combo with translated values

' and only allow user to type in values from the list

Table1.VlistStyle = GVLS_COMBO Or GVLS_TRANSLATE Or GVLS_VALIDATE

 Display ColumnButton

Table1.ColumnButton(2) = True

' Define possible values from the database

Table1.VlistData(1) = " 1"

Table1.VlistData(2) = " 2"

Table1.VlistData(3) = " 3"

Table1.VlistData(4) = " 4"

' Define translated values to appear in dropdown

Table1.VlistText(1) = "Office"

Table1.VlistText(2) = "Lab"

Table1.VlistText(3) = "Branch"

Table1.VlistText(4) = "Conference"

 Allow only three value to be displayed at one time in the dropdown

Table1.ColumnComboMaxItems(2) = 3

' Set up value list for column 2

Table1.VlistColumn = 3

' Define value list as text value translated to a picture and

' allow the user to cycle through available options

Table1.VlistStyle = GVLS_TEXT Or GVLS_TRANSLATE Or GVLS_CYCLE

' Define possible values from the database

Table1.VlistData(1) = " 0"

Table1.VlistData(2) = "-1"

Table1.VlistData(3) = "99"

' Define all values other than 0 and -1 as unknown

Table1.VlistDefault = 3

' Define translated picture to appear in column

Table1.VlistPicture(1) = LoadPicture("chkoff2.bmp")

Table1.VlistPicture(2) = LoadPicture("chkon2.bmp")

Table1.VlistPicture(3) = LoadPicture("chkgry2.bmp")


VlistCount property example

This code can be placed in a button to turn off all the value list columns and revert them to the column to a normal appearance.

For ct = 1 to Table1.Columns

Table1.VlistColumn = ct

Table1.VlistCount = 0

Next ct


ColumnSum, ColumnSumEnable property, and ColumnSumChange event example
ColumnSum, ColumnSumEnable properties, and ColumnSumChange event example

Demonstrates how to set up a column to maintain a summary value.

Form_Load

 Enable column summary

Table1.ColumnSumEnable(1) = True

'Set seed value for column sum

Table1.ColumnSum(1) = PrevCalcTotal

End Sub

Maintain the display value in the ColumnSumChange event.

Table1_ColumnSumChange

 Get sum from table

Total% = Table1.ColumnSum(1)

 Display sum in text box

Text1.Text = Format$(Total%, Currency)

End Sub


LayoutChange event example

This example allows you to save the layout to a binary file when the user makes changes to the grid.

Sub Table1_LayoutChange (Action As Integer, Split As Integer, Col As Integer)

    ' Open a file for Binary input

    Open "layout.txt" For Binary As #1

    ' Save Layout string to the binary file

    LayoutVar = Table1.Layout

    Put #1, , LayoutVar

    ' Close binary file

    Close #1

End Sub

This button click event reloads the layout from the binary file

Sub Command1_Click ()

    ' Open binary file read layout string and close the file

    Open "layout.txt" For Binary As #1

    Get #1, , LayoutVar

    Close #1

    ' Reset the Layout variable

    Table1.Layout = LayoutVar

End Sub


ComboSelect event example

When using a automatic dropdown combo box it is still possible to edit the value of the cell both before and after the user has selected a value from the list.  You may not want the user to be able to edit that cell at all.  If that is the case then put the following code in the grid.

Sub Table1_RequestEdit (cancel As Integer, KeyAscii As Integer)

If Table1.ColumnIndex = 1 Then	Value list column

Cancel = True

End If

End Sub

Sub Table1_ComboSelect()

Table1.EditActive = False

End Sub


PointX, PointY, RowAtPoint example

This event allows you to select a row to add to the BookmarkList using just a single click of the mouse.

Sub Table1_MouseUp (Button As Integer, Shift As Integer, X As Single, Y As Single)

     Set grids pointx and y properties to the mouses x and y

    Table1.PointX = X

    Table1.PointY = Y

     Move the grid to the mouse location

    Table1.RowIndex = Table1.RowAtPoint

     Allow grid to respond to setting RowIndex

    DoEvents

      Check to see if current row is already in bookmarklist

    For ct = 0 To Table1.BookmarkCount - 1

        If Data1.Recordset.Bookmark = Table1.BookmarkList(ct) Then

            Table1.BookmarkList(ct) = ""

            Exit Sub

        End If

    Next ct

     If not in list then add to list

    Table1.BookmarkList(Table1.BookmarkCount) = Data1.Recordset.Bookmark

End Sub


ColumnAtPoint Example

This example will allow you to determine when the user has clicked on the grid headings.  When RowAtPoint is zero the mouse is in the heading and we check the ColumnAtPoint to make sure that the mouse is not in the scrollbar and you can also use it do manipulation on that column as in this example where we toggle the color of the column.

Sub Form1_Load()

Disable grids ability move columns

Table1.Configurable = False

End Sub

Sub Table1_MouseUp (Button As Integer, Shift As Integer, x As Single, y As Single)

Table1.PointX = x

Table1.PointY = y

CurCol = Table1.ColumnAtPoint

If Table1.RowAtPoint = 0 And CurCol > 0 Then

If Table1.ColumnBackColor(CurCol) = BLUE Then

Table1.ColumnBackColor(CurCol) = GREY

Else

Table1.ColumnBackColor(CurCol) = BLUE

End If

End If

End Sub


ColumnText Example

This examples shows you to how to check the contents of the entire row before the data is updated to the database.  Using the data control Validate event and Save parameter you can check the values in each column and determine if more input is needed, display a warning, or allow the update or add to take place.

Sub Data1_Validate (Action As Integer, Save As Integer)

 Save is True when a change to the database is about to occur

    If Save Then

        If Table1.ColumnText(1) = "" Then

            MsgBox "You need to place a value in Column 1"

             Cancel save, set ColumnIndex to one, and ignore the action

            Table1.ColumnIndex = 1

            Save = False

            Action = 0

        End If

    End If

End Sub


splits

Splits are separate areas of the grid, each with their own column layouts, scrollbars, and optionally many other characteristics.  Splits are similar to the "split window" capabilities present in many products like Excel and Word for Windows, but have many customizable capabilities.  Splits can be created interactively by the user, or may be created and manipulated in Visual Basic code.  They can be locked (so that users can't change them interactively) or unlocked so that the user may control them directly via "split bars" which appear next to the horizontal scrollbar area.


marquee

The marquee is the visual cue TrueGrid provides to let you know which cell is current.  By default, the marquee is a dotted border around a cell, but you can change the marquee to several other styles using the MarqueeStyle property.


calculated column

A column whose ColumnExpression property contains a Visual Basic expression which is automatically evaluated by TrueGrid to derive the displayed data, rather than being fetched directly from a database field.  TrueGrid supports the full Visual Basic expression syntax, and over 35 of the most useful Visual Basic functions.


unbound column

An unbound column is a column which contains programmer-supplied data, rather than being fetched directly from the database or being calculated automatically by TrueGrid.  To implement unbound columns, you need to set the ColumnType for the column to "1 - unbound" and also write code in the UnboundFetch event to provide data for the column.


split-specific properties

Many TrueGrid properties may have different values for each split.  When accessing these properties, the property value is always dependent upon the current value of SplitIndex.  When setting these properties, they will be set for all splits if SplitPropsGlobal is True and will be set only for the current split if SplitPropsGlobal is False.  Here is a complete list if the split-specific TrueGrid properties:

AddRegexAttr	BottomRow	ColumnAddRegexAttr	ColumnBackColor

ColumnCellAttrs	ColumnFontStyle	ColumnForeColor	ColumnHasRegexAttr

ColumnHeadFontStyle	ColumnIndex	ColumnOrder	ColumnRectLeft

ColumnRectWidth	ColumnSetStatusAttr	ColumnStyle	ColumnVertScroll

ColumnVisible	ColumnWidth	Configurable	CurCellVisible

EditBackColor	EditForeColor	ExtendRightCol	HasRegexAttr

HeadBackColor	HeadFontStyle	HeadForeColor	HeadingHeight

HorzColor	HorzScrollbar	InactiveBackColor	InactiveForeColor

LeftColumn	MarqueeStyle	RightColumn	SelectedBackColor

SelectedForeColor	SelectMode	SetStatusAttr	SplitEditable

SplitGroup	SplitLocked	SplitSelectable	SplitSize

SplitSizeMode	SplitTabMode	TopRow	VertColor

VertLines	VertScrollbar


locked split

A locked split is a split which cannot be moved or resized by the user or at design time.  A locked split has its SplitLocked property set to True and it is the default state for all TrueGrid splits.  Locked splits don't have a split size box next to their horizontal scrollbar.  Setting SplitLocked to False for a given split will allow users to modify the size of splits, and will enable design-time modification of the splits's size.


locked column

A locked column is a column which is visible in one split, usually the leftmost split, while columns in other splits are horizontally scrollable.  Normally, locked columns are placed in a special split, configured for locked columns by having their SplitSizeMode set to "2 - Number of columns" and the SplitLocked property set to True.  However, locked columns are actually an illusion created by configuring splits and their columns appropriately.


split size box

Any unlocked split has a small black box immediately to the left of its horizontal scrollbar.  For the leftmost split, this box allows you to create a new split by dragging the box to the right.  For other splits, this box allows you (or your users) to change the size of the split by dragging the split boundary.


attribute precedence

This is the order in which the grid applies both color and font style to the grid.  Using the following list you can determine what property settings will take priority over others.  Grid settings are applied first and have the lowest priority.  The FetchAttributes event is applied last and has the highest priority.

1.	Overall Settings (ForeColor, BackColor, FontBold, FontItalic, FontUnderline)

2.	Column Settings (ColumnForeColor, ColumnBackColor, ColumnFontStyle)

3.	Selected Color Settings (SelectedForeColor, SelectedBackColor)

4.	Global Regular Expression (AddRegexAttr)

5.	Global Cell Status (SetStatusAttr)

6.	Column Regular Expression (ColumnAddRegexAttr)

7.	Column Status (ColumnSetStatusAttr)

8.	FetchAttributes Settings (ColumnCellAttrs, FetchAttrs event)


global properties

Global properties are properties which are always applied to all splits, regardless of the setting of SplitPropsGlobal.  If a property is global, then its value is not dependent upon the current split (designated by the value of SplitIndex).  By contrast, split-specific properties can be different for each split.


cell status

A combination of characteristics which identifies the disposition of a displayed cell.  A cell can be (a) the current cell, (b) a cell within the current highlighted row, (c) a cell within a marked row, or (d) a cell in which data has been modified by the user.  A cell can be any combination of these characteristics, making a total of 16 possible status combinations for all cells.   Cell status is generally used when setting per-cell colors and fonts for cells.


bit mask

An integer or long value in which each bit has a meaning.  The numeric value of a bit mask is usually not meaningful unless the Visual Basic And and Or operators are used to isolate individual bits.  Each bit in a bit mask is represented by a power of two.  The low-order bit (least signficant) has a value of 1, the second bit has a value of 2, the third has a value of 4, and so on.  Bit masks are often convenient ways to represent collections of boolean values.


regular expression

A pattern-matching expression (popularized by Unix) in which certain characters have a special meaning.  For example, "A*" means to match 0 or more occurrences of an "A".  "A+" means to match 1 or more occurrences.  "[0-9]+" will match any string of digits because it means to match 1 or more occurrences of consecutive characters in the range 0-9.  The characters, [, ], *, +, ^, \ , the period, and $ have special meanings within regular expressions.  All other characters are interpreted literally and are case-insensitive, so the regular expression "visual basic" will match the string "Visual Basic", "visual Basic", and "ViSuAL BaSIC".  TrueGrid uses standard Unix regular expressions which are not compatible with those used in the Visual Basic Like operator, but are more powerful.


font style

An integer value specifying one of eight separate font styles:  1=Normal, 2=Bold, 3=Italic, 4=BoldItalic, 5=Underline, 6=Bold+Underline, 7=Italic+Underline, 8=BoldItalic+Underline.  Often, font style parameters also accept the value 0 (defined as INHERIT_FONT in TGCONST.TXT) which indicates that the style of the font is to be inherited from the grid font settings (defined with the FontBold, FontItalic, and FontUnderline properties).


drag-and-drop operation

A user action which involves picking up a control (or data from a control) and dropping it into another control.  Drag-and-drop must be implemented by the programmer using Visual Basic events DragOver, DragDrop and the Drag method.  TrueGrid provides a special event, DragCell, which simplifies dragging data from a grid cell or row.


callback mode

Sometimes called "Application mode".  In this mode, TrueGrid is not bound to a database.  All data must be provided to the grid using the Fetch event.   Callback mode (or database mode) is chosen at design time by using the DataMode property.


 TGUTILS.BAS:  TrueGrid Utility Functions

TrueGrid is provided with a set of utility functions for performing common operations.  The utility functions are written in Visual Basic code and can easily be included in your projects by using the "Add File..." option of the Visual Basic "File" menu.

The utility functions also serve as good examples of how to write TrueGrid code to accomplish similar tasks.  You are free to use the utility functions in any way you wish, or can modify them to suit your own purposes.

Split Management Functions

TgLockColumnLeft	Used at runtime to lock any column in the leftmost split.  Works like the "locked at left" checkbox in the Column Properties Dialog, except provides this feature at runtime.

TgLockColumnRight	Like TgLockColumnLeft, except that it will lock a column in a rightmost split, creating a locked split if need be.  Both left and right locks can be used simultaneously.

TgUnlockColumn	Unlocks a column which is locked at the left or right using TgLockColumnLeft or TgLockColumnRight.  Will also unlock columns which were "locked at left" at design time.

Color Management

TgSetCurCellColor	Sets the foreground and background color of the current cell.  Overrides normal highlighting of the current cell.

TgSetMarqueeColor	Sets the foreground and background color of the highlighted row marquee when MarqueeStyle specifies a highlighted row.

TgSetNegativeColColor	Sets the foreground and background color used for cells which display negative numbers within the specified column.

Column Information

TgFindColumn	Given a string which identifies a column field or heading, returns the column index of the desired column.

TgGetVisibleCols	Returns the number of columns which are currently visible within the current split.


TgFindColumn (TGUTILS)

Syntax	col% = TgFindColumn(gridctl, text$)

This function will search the column list to find the column index for a column whose fieldname or heading matches the string specified by text$.  The match is not case-sensitive.

This function returns the number of the column which was found, or zero (0) indicating that there is no such column.

The function searches the list of ColumnField values first, then if it does not find a match, searches the ColumnName values for all columns.

Usage	This function should be used when it is difficult to keep track of the integer column numbers of columns your code refers to.  Although the runtime column numbers will always be consistent with those used at design-time, this function makes it unnecessary to maintain column numbers in your code whenever you change the design-time layout.

TgFindColumn should be used to store the column number in a local or global variable if the result will be used frequently.  This will save on execution time.  For example, it may be a good idea to store frequently used column numbers in Form_Load, then use those variables elsewhere in your code.

Example	The following example shows how TgFindColumn can be used to set the column properties for a column:

col% = TgFindColumn(Table1, "Balance")

Table1.ColumnForeColor(col%) = RED

Table1.ColumnBackColor(col%) = WHITE


TgGetVisibleCols (TGUTILS)

Syntax	vcols% = TgGetVisibleCols(gridctl)

This function returns the number of visible columns within the current split of gridctl.  A visible column has its ColumnVisible property set to True.

Usage	This function is useful if you allow users to reconfigure and hide columns, or if your code wants to know whether any visible columns remain (For example, to remove a split once all the visible columns are gone).  This function is used in the source code for the TgUnlockColumn utility function to determine whether the locked split needs to be removed.

Example	The following example hides a column in the current split, then removes the split if there are no remaining visible columns:

tohide% = TgFindColumn("AccountNum")

Table1.ColumnVisible(tohide%) = False

If TgGetVisibleCols(Table1) = 0 Then

Table1.RemoveSplit = 0

End If


TgLockColumnLeft (TGUTILS)

Syntax	TgLockColumnLeft gridctl, colno%

This function places a column at the leftmost part of the grid while allowing the remaining columns to scroll horizontally.  Typically, this is referred to as a "locked column".  The column number specified by colno% will be locked.  If it is already locked, then no action is taken.

This function performs identically to the design-time "Locked at left" checkbox available in the Column Properties Dialog but can be accomplished at runtime.

Usage	TgLockColumnLeft is typically used to provide users with a non-scrolling region of the grid, or is used when configuring column layouts at runtime rather than using the Layout Editor at design time.  This function can be used in conjunction with TgLockColumnRight to create locked regions on both the left and right part of the grid.

More than one column can be locked, by calling this function repeatedly with a different column.  To unlock a locked column, use TgUnlockColumn.

Example	The following example locks the "Title" column at the left of the grid:

TgLockColumnLeft Table1, TgFindColumn(Table1, "Balance")

How it works	TgLockColumnLeft works by defining splits which contain the locked columns.  By convention, the left split contains locked columns if:

1.	The split has its SplitSizeMode set to "2 - Number of columns".

2.	The split has its SplitLocked property set to True.

In reality, this is only a convention, used both at design time in the Column Properties Dialog, and at runtime by this function.  Using the split properties, you can create much more sophisticated effects yourself.

Examining the code for the TgLockColumn function (which actually does the work) may be instructive if you are experimenting with splits.


TgLockColumnRight (TGUTILS)

Syntax	TgLockColumnRight gridctl, colno%

This function places a column at the rightmost part of the grid while allowing the remaining columns to scroll horizontally.  Typically, this is referred to as a "locked column".  The column number specified by colno% will be locked.  If it is already locked, then no action is taken.

This function is similar to the design-time "Locked at left" checkbox available in the Column Properties Dialog but locks the specified column at the right instead.

Usage	TgLockColumnRight is typically used to provide users with a non-scrolling region of the grid, or is used when configuring column layouts at runtime rather than using the Layout Editor at design time.  This function can be used in conjunction with TgLockColumnLeft to create locked regions on both the left and right part of the grid.

More than one column can be locked, by calling this function repeatedly with a different column.  To unlock a locked column, use TgUnlockColumn.

Example	The following example locks the "Title" column at the right of the grid:

TgLockColumnRight Table1, TgFindColumn(Table1, "Balance")

How it works	TgLockColumnRight works by defining splits which contain the locked columns.  By convention, the left split contains locked columns if:

1.	The split has its SplitSizeMode set to "2 - Number of columns".

2.	The split has its SplitLocked property set to True.

In reality, this is only a convention, used both at design time in the Column Properties Dialog, and at runtime by this function.  Using the split properties, you can create much more sophisticated effects yourself.

Examining the code for the TgLockColumn function (which actually does the work) may be instructive if you are experimenting with splits.


TgUnlockColumn (TGUTILS)

Syntax	TgUnlockColumn gridctl, colnum%

This function unlocks a column which has been previously locked using TgLockColumnLeft, TgLockColumnRight, or has been locked at design time using the Layout Editor's Column Properties Dialog.  The locked column will be hidden in the left or right split where it is visible, and shown in the remaining splits.  The left or right split containing the locked column will be removed if necessary.

Usage	This function is used to unlock a column from the left or right split where it has been previously locked.  The function will automatically determine where the locked column resides, so it is not necessary to specify whether the column is locked on the left or right when calling this function.

Example	The following example unlocks the column called "PartNo":

TgUnlockColumn Table1, TgFindColumn("PartNo")


TgSetMarqueeColor (TGUTILS)

Syntax	TgSetMarqueeColor gridctl, FgColor&, BgColor&

This function sets the foreground and background color for the marquee, including the current cell.  FgColor& specifies the new foreground color, BgColor& specifies the new background color.  Either value may be set to INHERIT_COLOR (-1) meaning that the standard color for the marquee should be used for that attribute.

This call takes effect immediately and will be reflected in the grid marquee.

Usage	Use this call whenever you want to change the foreground color, background color, or both for the marquee.  This call will change the marquee color for all values of MarqueeStyle.  If MarqueeStyle specifies dotted cell or solid cell, then the cell will be outlined with a dotted box or solid box in addiiton to being displayed in the chosen colors.

After making this call, the current cell and all other cells in the marquee row will have the same color.  If you want to make the current cell have different color attributes, then call TgSetCurCellColor after you set the marquee color with this call.

Example	The following call sets the marquee background color to BLUE (defined in CONSTANT.TXT), but leaves the foreground color as the default:

TgSetMarqueeColor table1, INHERIT_COLOR, BLUE

How it works	This subroutine uses SetStatusAttr to set the color for all cell status values which include the marquee.  Using SetStatusAttr directly affords much more flexibility and control, but often involves more coding in simple cases where marquee or current cell colors are changed.


TgSetCurCellColor (TGUTILS)

Syntax	TgSetCurCellColor gridctl, FgColor&, BgColor&

This function sets the foreground and background color for the current cell, but not other cells which are part of a highlighted row marquee.  FgColor& specifies the new foreground color, BgColor& specifies the new background color.  Either value may be set to INHERIT_COLOR (-1) meaning that the standard color for the current cell should be used for that attribute.

This call takes effect immediately and will be reflected in the displayed current cell.

Usage	Use this call whenever you want to change the foreground color, background color, or both for the current cell.  This call will change the color for all values of MarqueeStyle.  If MarqueeStyle specifies dotted cell or solid cell, then the cell will be outlined with a dotted box or solid box in addiiton to being displayed in the chosen colors.

If you want to make the current cell have different color attributes than the rest of a highlighted row, then use TgSetMarqueeColor first, then set the current cell color with this call.

Example	The following call sets the current cell to white text on a blue background:

TgSetCurCellColor table1, WHITE, BLUE

How it works	This subroutine uses SetStatusAttr to set the color for all cell status values which include the current cell.  Using SetStatusAttr directly affords much more flexibility and control, but often involves more coding in simple cases where marquee or current cell colors are changed.


TgSetNegativeColColor (TGUTILS)

Syntax	TgSetNegativeColColor gridctl, colnum%, FgColor&, BgColor&

For a given column, colnum%, within the current split, this function sets the color to be used for cells which contain negative values.  A negative value is defined as one which starts with a "-" symbol, or one which is enclosed in parenthesis.  After this call, any cell which matches that pattern will assume the colors specified by FgColor&, and BgColor&.  Either can be set to INHERIT_COLOR (-1) to specify that the default foreground or background color is to be used instead.

Usage	Use this function to cause cells containing negative values to appear given a certain color.  This function provides limited functionality for per-cell colors, since it defines negative values in a very specific way.  Much more flexibility is provided using AddRegexAttr or ColumnAddRegexAttr, but this call provides simple default behavior for the most common cases.

Example	Set the column called "Balance" so that negative numbers appear with red foreground lettering and a default background:

col% = TgFindColumn(Table1, "Balance")

TgSetNegativeColColor Table1. col%, RED, INHERIT_COLOR

How it works	This function uses ColumnAddRegexAttr to specify a pattern match for cells in the column.  The following two patterns are used:

1.	"^ *-"  This pattern matches any cell which starts with a "-" symbol, with optional leading spaces.

2.	"^(.+)$"  This pattern matches any cell which starts with a left parenthesis and ends with a right parenthesis.


 Overview of Sample Code

TrueGrid comes with a collection of sample programs which were installed in your TrueGrid installation directory.  If you run each of these programs, you can access their help files directly from the sample help menu.

If you like, you may want to browse the sample help files now:

  TrueBrowser Sample Help	TrueBrowser is a complete browser which is provided in source code.  It can browse any Visual Basic 3.0 database.

  dBTable Sample Help	dBTable is a sample application which shows how to use TrueGrid without being directly connected to a database.  In other words, to display any kind of data.  The sample shows how the field structure of a dBASE file can be displayed and edited.

  LinkGrid Sample Help	The LinkGrid sample shows how two TrueGrids can be linked together to show related data.  This sample also demonstates TrueGrids printing capabilites.

  MarkGrid Sample Help	The MarkGrid sample shows how multiple selections can be managed with TrueGrid and how TrueGrid responds to SQL queries. This sample also demonstrates TrueGrids printing capabilites.

  Appointment Book Sample Help	The Appointment Book sample covers several different topics as well as being a practical application.

  General Ledger Sample Help	General Ledger uses an accounting example to illustrate several of the grid's advanced features.

  Drag and Drop Sample Help	Shows how easy it is to drag cells from the grid and drop them into another grid.  Special properties and events for performing drag-drop are demonstrated.

  Dropdown Sample Help	Demonstrates linking other controls to TrueGrid cells.  Properties for cell location and editing are illustrated.

  Editing Sample Help	Covers several methods of validating user entry.  Most editing properties are used in this sample.

  Order Entry Sample Help	Illustrates using TrueGrid's Column Summary feature

  In-Cell Graphics Sample Help	Demonstrates several ways to implement value lists

  Callback Sample Help	Very simple example of how to use the grid in application or callback mode.

  Table View Sample Help	Shows how to attach a TrueGrid to a Visual Basic Table object (without the Data Control).


True Browser Help Index (sample)
  True Browser Help Index

  An overview of the Browser's features.

  A brief description of each menu item.

  How to use the TrueBrowser data table.

An overview of the Browser's features

True Browser is both a utility and sample all rolled into one.  You can use the Browser right out of the package as an easy to use database browser with full edit, query, and, sorting capabilities.  TrueGrid supports all databases that Visual Basic recognizes:

--	Microsoft Access-format databases.

--	External databases which include Btrieve, dBASE III, dBASE IV, FoxPro 2.0 and 2.5, and Paradox.

--	External ODBC databases.

This initial version of the Browser provides support for the Microsoft Access-format databases, and all external databases except external ODBC databases.  We do not provide support for external ODBC databases in the True Browser because they are accessible only in the Professional Version of Visual Basic.

But wait!  You also get the source code, complete and documented so that you can personalize your version.  The source provides you an opportunity to see how to 'hook' the database up to the data control, and even how you might go about developing your own general purpose browser.  You can easily add ODBC database support to the Browser by modifying the source code provided.

The Browser is a tool for viewing and editing any database that can be opened by the Data Control.  It supports the following features:

--	Microsoft Access (.mdb), dBASE (.dbf), FoxPro (.dbf), Btrieve [.ddf and .dat], and Paradox (.db) file formats are supported.  Remember TrueGrid supports all formats that Visual Basic Data Access supports.

--	Records are displayed in a scrollable grid that behaves like a standard browse table.

--	Columns may be moved and resized with the mouse.

--	Scrollable forms for updating and adding records are built dynamically according to the database field structure.

--	Scrollable QBE (query by example) form makes record query easy and intuitive for the end user.

--	Records in the current selection set may be sorted or viewed in natural order.

--	Fields which may contain a large amount of text, such a dBASE memo fields, may be viewed and edited in a separate window by choosing the Update option from the Record menu option and then clicking the ZOOM button on the Update form.

--	Ability to select multiple records.  The feature uses the SelectMode property.

Menu Commands

File Menu

Open...	Open Database Table

Close	Close Database Table

Exit	Exit True Browser

Record Menu

Add...	Add a record to the database

Update...	Update database record

Delete	Deletes a record in the database

Sort Menu

UnSorted	Returns the current table to an unsorted order

<filename>	Sorts the database on the chosen filename

More Fields...	Bring up more fields from which to sort by

Query Menu

Find...	Allows you to do a Find on the database

Find All	Removes find criteria from the database

Help Menu

Index...	Brings up first frame of this help file

Using Help... 	Shows you how to use WinHelp application

About Browser...
Brings up Version information for TrueGrid

Using the True Browser Data Table

Navigating

The current row on the grid is identified by a shaded marquee which runs the length of the record. Make another row current by clicking on it, or using the keypad navigation keys.

To scroll the contents of the grid up or down, use the vertical scroll bar or the numeric keypad navigation keys.  To scroll the contents of the grid left or right, use the horizontal scroll bar.  This version does not provide any key bindings for horizontal navigation.

Formatting

To resize a column, grab the vertical line at the column's right edge and drag it to the desired location.  Columns have a minimum width of one character or may be removed altogether.

To move a column, grab its heading (the cell in which its field name is displayed) and drag it to the desired location.

Editing Data

To edit the contents of a cell, first make the row current. Next click anywhere within the desired cell's boundaries. The cell will be highlighted, and an edit cursor will appear at the beginning of the cell's text. Use the left and right arrow keys to position the cursor within the cell. Typed characters are inserted at the current cursor position.

To get out of edit-mode, click on another cell or press the up or down arrow key. Any changes made to the edited cell will be committed to the database.

Selecting Multiple Rows

If you want to have multiple rows selected in the grid you can do the following.  Position the mouse at the far right of the record you want to select.  The mouse pointer should change to a check mark.  At this point simply click the right mouse button and the row should highlight in a different color.  You can select as many rows as you want.  To de-select a row repeat the same procedure.  For more information see the SelectMode property.


Open Command (True Browser)
Open...

This command enables you to open a database file to browse. Any VB Data Access-Supported database file can be opened, except for ODBC databases.

Upon selecting the Open... option, a File Open dialog box will displayed . The essential purpose of this dialog box is to provide an easy means of selecting a database file to browse. Once a file has been selected, the OK button can be clicked to open the file and display its contents in the Browser. If the CANCEL button is selected, the dialog box will close and you will be returned to the Browser.

In addition to the buttons, the File Open dialog box contains various text controls, combo boxes, and other helpful information. The drive and path displayed directly underneath Directories at the upper middle portion of the dialog box is called the current directory. The current directory can be changed simply by double clicking on any of the entries in the Directory list box. The current drive can be changed, by selecting from any of the drives listed in the Drives combo box.

The File list box, by default, displays all database files in the current directory that may be opened by the Browser.  To open one of these listed files, click the file name then select the OK button. Double-clicking on the filename will do the same thing.

You can also type a filename into the File Filter text box, then select OK to open the file. If a full path and filename is specified, that file will be opened, otherwise, the current directory will be used to determine the file's path.

Wild cards may also be entered into the File Filter text box. All files within the current directory that match a wild card will be listed in the File list box. Multiple wild cards may also be specified, as long as each one is separated by a semi-colon.

The File Filter combo box provides a quick way to list files with a certain database format. When you click the combo box's [image] button, it will list all of the available database file types supported by True Browser.  From this list, you can select a specific file type to display in the File list box

If the Read Only box is checked at the time you select the OK button, the file will be opened as read-only.

If the database format you choose requires additional information such as a specific format or a Table selection within the given database, True Browser will prompt you for this additional information in a Table list box.  DBF files require the format you wish to open them in (FoxPro or dBASE), MDB and DDF files will ask for a Table.  Paradox files (DB) are assumed to be any 3.X version.


Add Command (True Browser)
Add...

This command allows you to add a new record to the database. Upon selection of the Add option, a dialog box will be displayed, enabling you to assign values to each field in the new record (see the sample dialog box at the end of this help topic). Note that this option is only available for databases opened with read-write privileges.

The Add dialog box contains a text field for each field in the database. If there are more text fields than can fit in the box, scroll bars are also displayed.

A record may be added simply by entering data into one or more of the text fields, then clicking the ADD button. The dialog box will remain displayed so that multiple records may be added in succession. Close the dialog box at any time by clicking the DONE button.

The ZOOM button is useful for fields that may be very long, such as dBASE memo fields. When this button is clicked, a multi-line text window will be displayed, allowing you to enter multi-line text in an editor-like fashion.

The CLEAR button clears all of the fields in the Add dialog box.

Add Dialog Box


Update Command (True Browser)
Update...

This command allows you to update the current record of the database which is being browsed. The current record is identified as the row in the Browser's grid that the marquee is on. Note that this option is only available for databases opened with read-write privileges.

Upon selection of the Update option, a dialog box will be displayed, enabling you to modify the fields in the current record (see the sample dialog box at the end of this topic).

The Update dialog box contains a text field for each field in the database. If there are more text fields than can fit in the box, scroll bars are also displayed. Initially, these text fields contain the data that is stored in the current record.

A record may be updated simply by modifying data into one or more of the text fields, then clicking the UPDATE button. The dialog box will remain displayed so that multiple records may be updated in succession. Close the dialog box at any time by clicking the DONE button.

The ZOOM button is useful for fields that may be very long, such as dBASE memo fields. When this button is clicked, a multi-line text window will be displayed showing the field's data. Text can be entered into this window in an editor-like fashion.

The CLEAR button clears all of the fields in the Update dialog box.

The Navigation buttons enable you to move from one record to another so that you can easily perform updates to multiple records. The First button  makes the first record in the database current, and puts its data into the dialog box's text fields. Likewise, the Last button makes the last record current.

You can also move sequentially from record to record by using the Next button and Previous button.

Update Dialog Box


Find Command (True Browser)
Find...

This command allows you to query the currently opened database using a Query By Example format. Queries may be saved and re-used later. Note that the Find command is available only when a database has been opened.

Upon selection of the Find command, a dialog box will be displayed, enabling you to construct a QBE query (see the sample dialog box at the end of this topic).

The find dialog box contains a text field for each field in the database. The contents are originally blank. Queries are performed by typing search criteria into one or more of these text fields, then clicking the FIND or FIND ALSO buttons.

Search criteria can be specified by entering a relational operator and a value into the field to which the search will apply. For example, suppose our current database has the fields shown in the sample dialog box at the end of this topic. You may type "=Smith" into the LASTNAME field to find all people having a last name of "Smith".

The general syntax of a QBE query is simple,

relational-operator value

The relational operator can be any of  the following =, >, <, >=, <=, and <>. You may type one of these operators into a field, or click on one of the operator buttons.

If you want to use the relational operator =, you don't even need to specify it. In other words, simply typing Smith into the LASTNAME field will result in the query LASTNAME=Smith.

Multiple fields may be used in a query.  For example, to find all people in the sample database whose last name begins with a letter between A and R, and who live in the state of PA, the LASTNAME field would contain "<S" and the STATE field would contain "PA" and you would click the FIND button.  Clicking the FIND ALSO button would find all the people with a last name that begins with a letter between A and R, and it would also add to that list all the people that live in the state of PA.

Once a query has been created, clicking the FIND and FIND ALSO buttons will invoke a database search for all records matching the query. These records, known as the selection set, will be displayed in the browser. No other records will be displayed. Any subsequent queries will operate on the entire database!!!

The two other buttons on the Find dialog box are the CLEAR button, which will clear all of the text fields, and the DONE button which will close the Find dialog box, and return you to the browser.

Find dialog box


dBTable Help Index (sample)
 dBTable Help Index

   dBTable overview

  Creating the dBTable project

dBTable Overview

dBTable is a sample program to demonstrate how to use TrueGrid in callback mode (i.e., the DataMode property of the grid is set to 1 (Application)).  In this mode, the grid is not connected to a database file.  Instead, data in the grid will be supplied and maintained by the programmer while the grid takes care of all user interactions and data display.

dBTable allows the user to enter a dBASE file structure in a table format.  It is by no means a complete program, and it does not actually create a dBASE file after the user has entered a dBASE file structure in the table.  Its sole purpose is to illustrate how to use TrueGrid in "Application mode."

You do not need to understand dBASE nor its file structure to follow this sample program.  Just assume you are creating a program to allow users to enter information in a table format with the following specifications:

1.	Each row represents a field structure.

2.	Maximum number of fields (rows) allowed is 255.

3.	The table has six columns (used to describe a field structure):

col 1:	Field number (range 1 to 255)

col 2:	Field name. 1 to 10 characters.  Allows only upper case letters, digits, and "_".  First character must be an upper case letter.

col 3:	Field type. 1 character.  Allows only "C", "N", "F", "D", "L", or "M" only.  (Stands for Character, Numeric, Float, Date, Logical and Memo field types, respectively.)

col 4:	Field width.  1 to 3 characters.  Contains digits only. The field width for Date, Logical and Memo fields are fixed at 8, 1, and 10 characters, respectively.

col 5:	Field decimal width.  1 to 2 characters. Contains digits only.  The field decimal width applies to Numeric and Float fields only.

col 6:	Field index flag.  "Y" if field is indexed, "N" otherwise.

As you run the program and start entering data in the table, you will observe the following:

1.	As you move from one column to another, a (column) context sensitive help instruction will be displayed below the grid.

2.	As your enter the field name, all letters will be automatically capitalized, and only legal field name characters (letters, digits and "_") can be entered.

3.	As you enter a field type character, only legal characters ("C", "N", "F", "D", "L", or "M") will be accepted.

4.	Depending on the value of  the field type entered, default values of field width, field decimal width and field index flag will be automatically entered.

5.	Warning messages will be displayed and you will not be able to leave the current grid cell if you have entered an illegal field name (e.g., if the field name does not start with a letter) or illegal field widths (e.g., if  field decimal width is bigger than the field width).

6.	If a field type has fixed width or cannot be indexed (see column descriptions in 3. above), the grid will not permit editing of the field width or the field index flag columns.

7.	If you press the down arrow key, a new row will be appended to the table. However, if you already have 255 rows in the table, you can no longer append additional rows.

The above features make the program very user-friendly and easy to use.  You will learn how to make use of various TrueGrid events to develop this user-friendly, table-entry application.  The events used in this application are only some of the TrueGrid events available.  After learning this application, you should familiar yourself with all available TrueGrid events and start using them to create your own user-friendly applications.  The major components of this application are described in the Creating the dBTable project section.


dBTable Help Index (sample)
 dBTable Help Index

   dBTable overview

  Creating the dBTable project

  3-D TrueGrid

  The field structure array

  The Form Load event

  The TrueGrid Fetch event

  The TrueGrid Update event

  The TrueGrid KeyPress event

  The TrueGrid Validate event

  The TrueGrid ColumnChange event

Creating the dBTable project

Assuming you have installed TrueGrid in C:\TRUEGRID, All source code for the dBTable application is included in the C:\TRUEGRID\DBTABLE subdirectory.  The main form contains a TrueGrid with DataMode property set to 1 (Callback).  All declarations and code necessary to implement dBTable are in C:\TRUEGRID\DBTABLE\XFORM1.BAS.  The following sections describe the major elements of the dBTable application:

3-D TrueGrid

The 3-D look of the grid is achieved by setting the following TrueGrid properties:

BackColor = &H00C0C0C0& (light gray)

HorzLines = VertLines = 2-3D

HorzColor = VertColor = &H00808080& (dark gray)

You may want to examine the properties table of TrueGrid in the dBTable project at Visual Basic design mode.

The field structure array

In Application mode, the grid is not connected to a database and the program is responsible to maintain and store the data in the grid.  In this application, the table size is 255 rows by 6 columns.  So we use 6 Visual Basic arrays (one array per column) to store the field table:

' Array to store dBASE field structures

Dim FieldNo(1 To 255)  As String 	' Field number

Dim FieldName(1 To 255)  As String 	' Field name

Dim FieldType(1 To 255)  As String	' Field type

Dim FieldWidth(1 To 255)  As String	' Field width

Dim FieldDec(1 To 255)  As String	' Field decimal

Dim FieldIndex(1 To 255)  As String	' Field index flag

For very large tables (say 1,000,000 rows), this technique will not be practical since there may not be sufficient memory to hold all the array elements.  The programmer may then need to maintain and store the data in a file.  In Database mode (when the grid is connected to a database file) TrueGrid will be responsible for retrieving and updating the data.

The Form Load event

The Form _Load event is used to initialize the field arrays and also to initialize the grid properties.

See also Form_Load in C:\TRUEGRID\DBTABLE\XFORM1.BAS for details.

The TrueGrid Fetch event

Whenever the grid needs to display data in a cell, it will ask the programmer for the appropriate data to display via the TrueGrid Fetch event.  The programmer cannot make any assumption as to when the grid will ask for data.  Also, the programmer cannot make the assumption that if data for a certain row/col is asked once, the grid will not ask for it again.  In short, it's the programmer's responsibility to store and maintain the data, and it's the grid's responsibility to display them properly.

This technique will completely free the programmer from worrying when and how to display data in the grid.  For example, if the user drags a window to (partially) covers the gird and later remove the window, the grid will be responsible to know about it and refresh the data in the grid.  The programmer needs only to maintain and store the data but need not worry about user interactions and Windows display.

See also xFieldTable_Fetch in C:\TRUEGRID\DBTABLE\XFORM1.BAS for details.

The TrueGrid Update event

After the user has finished editing data in a cell and the data has been validated by the program via the TrueGrid Validate event, the grid will then notify the programmer the cell now has a new value via the TrueGrid Update event.  In this event, the programmer uses the value supplied by the grid to update the data he is responsible for storing and maintaining.  In this application, the field structure arrays are updated by the new values supplied by the gird.

See also xFieldTable_Update in C:\TRUEGRID\DBTABLE\XFORM1.BAS for details.

The TrueGrid KeyPress event

This TrueGrid KeyPress event illustrates a few techniques to check, modify, and restrict user input.  For example, all letters entered by the user are converted to upper cases in this event.  Also, illegal field name and field type characters will not be accepted by this event.  The goal is to assist user to enter valid data thus making the program more user friendly.

See also xFieldTable_KeyPress in C:\TRUEGRID\DBTABLE\XFORM1.BAS for details.

The TrueGrid Validate event

After the user finish editing in a cell and before moving to another cell, this event allows the programmer to examine the value in the current cell.  If the value entered is invalid, programmer can (optionally) display a message, then set Cancel to True to prohibit the user from moving on to another cell.  The TrueGrid Validate and KeyPress events together provide a very easy way for programmers to check, restrict and validate user inputs in TrueGrid.

See also xFieldTable_Validate in C:\TRUEGRID\DBTABLE\XFORM1.BAS for details.

The TrueGrid ColumnChange event

We make use of the TrueGrid ColumnChange event to display a different help string when the user is at different table column.  This is to make the program more user friendly by providing context sensitive instructions during the data entry process.

See also xFieldTable_ColumnChange in C:\TRUEGRID\DBTABLE\XFORM1.BAS for details.


LinkGrid Help Index (sample)
 LinkGrid Help Index

  LinkGrid overview

  Creating the LinkGrid project

LinkGrid Overview

The LinkGrid sample program demonstrates:

1.	Creating a database browser using TrueGrid

2.	Using TrueGrids to relate and display 2 databases.

3.	How to print a Crystal Report using TrueGrid.

If you run the LinkGrid application, you will see 2 grids displaying 2 databases: The composer table on top and opus table at the bottom.  Each record in the composer table contains the first name, last name, country, date of birth and date of death of a composer.  A composer appears in one and only one record in the composer table.  Each record of the opus table contains the last name and a music piece the composer has created.  Since a composer generally has created more than one music piece, a composer may appear in more than one record in the opus table.

Notice that in the bottom grid, only records with the same last name as the current row, (record) of the top grid are displayed.  As you navigate through the top grid (either by clicking any row in the grid, clicking on the scroll bar of the grid, or clicking on the buttons of the Data Control),  the set of records in the bottom grid changes accordingly.

This simple but useful application can easily be created using TrueGrid as described in the Creating the LinkGrid project section.


LinkGrid Help Index (sample)
 LinkGrid Help Index

  LinkGrid overview

  Creating the LinkGrid project

  Setting Data Control properties

  Setting TrueGrid properties

  Setting Crystal VBX properties

  Setting DatabaseName property in the Form Load event

  Linking the grids in the TrueGrid RowChange event

Creating the LinkGrid project

Assuming you have installed TrueGrid in C:\TRUEGRID, All source code for the LinkGrid application is included in the C:\TRUEGRID\LINKGRID subdirectory.  The main form contains 2 Data Controls (Data1 and Data2), 2 TrueGrids (Table1 and Table2), and 1 Crystal VBX (Report1).  This application requires very little code.  Just set the properties and add code as described in the following sections.

Setting Data Control properties

For Data1, set the following properties:

Caption	Composer Database

RecordSource	composer

For Data2, set the following properties:

Caption	Music By Composer

RecordSource	Opus

The DatabaseName properties (which contain the directories where the databases reside) of Data1 and Data2 are not set.  This is because we do not know where you have installed TrueGrid.  Hence we defer setting the DatabaseName properties to the Form_Load event as described in the Setting DatabaseName property in Form_Load section.

Note also that the RecordSource property of Data2 is not set.  We do not want to display all the records in the opus table.  The RecordSource of Data2 will be determined by the value of the last name field of the current row (record) of Data1.  It will be specified in the Table1 RowChange event as described in Linking the grids in the TrueGrid RowChange event section

If we set the RecordSource property of Data2 to "opus" at design time.  The program will still run correctly except that when the form is first loaded, you will first see the entire opus table displayed in the bottom grid for a moment.  As soon as the current row of Table1 is settled, the Table1_RowChange event will be executed, and Table2 will be refreshed according to the current value of the last name field in Table1.  Skipping the DataSource property of Data2 will avoid the flicker at the beginning of the program.

Setting TrueGrid properties

Link (bound) Table1 to Data1 by setting the following property:

DataSource	Data1

Link (bound) Table2 to Data2 by setting the following property:

DataSource	Data2

Table1 is used to display the composer table.  The 4th and 5th fields of the database are the composer's birth and death dates, respectively.  We wish to display the dates in mm/dd/yyyy format (default date format is mm/dd/yy).  We can define the EditMask property at design time using the Layout Editor  But, instead, we will define the EditMask in the Form_Paint event at run time as follows:

Table1.EditMask(4) = "mm/dd/yyyy"

Table1.EditMask(5) = "mm/dd/yyyy"

Setting Crystal VBX Properties

Setting up printing from the grid is very easy.  Simply drop a Crystal VBX icon on the from and set the following properties:

ReportSource: 1 - Bound TrueGrid Control

BoundReportFooter: True

DataSource: Data1

Then in the OpusReport menu option the Report controls BoundReportHeading is set to the Composer's name and the Action property is set to one (1).  When clicked a Crystal preview window will appear with the selected Composer's name in the heading and his compostions displayed as records.

Setting DatabaseName property in the Form Load event

The DatabaseName property of  the Data Controls should be set to the directory name containing the databases.  Assuming you install TrueGrid in C:\TRUEGRID, the application and the databases will be located in the C:\TRUEGRID\LINKGRID subdirectory.  Since you may install TrueGrid in other directories, we will not specify the DatabaseName during Visual Basic design time.  Instead, we use the App.Path property to determine the directory where the databases are stored in the Form_Load event:

Data1.DatabaseName = App.Path & "\linkgrid.mdb"

Data2.DatabaseName = App.Path	& "\linkgrid.mdb"

Linking the grids in the TrueGrid RowChange event

We use the following code in the RowChange event to relate the two databases such that Table2 displays only the records with the same last name as the current row (record) of Table1:

LastName$ = Data1.Recordset.Fields("Last").Value

Data2.RecordSource = "Select * From OPUS where Last="+Chr$(34)+LastName$+Chr$(34)

Data2.Refresh


MarkGrid Help Index (sample)
 MarkGrid Help Index

  MarkGrid Overview

  Creating the MarkGrid project

MarkGrid Overview

The MarkGrid sample program demonstrates:

1.	Marking selected records using TrueGrid.

2.	Using TrueGrid to display records selected by a SQL statement.

3.	Printing the results of an SQL statement.

If you run the MarkGrid application, you will see a grid displaying the composer table.  The application provides 2 ways to mark records on the grid:

1.	Move the mouse pointer near the left edge of the grid, you will see a check mark replacing the normal arrow mouse pointer.  Click on the row (record) you want to mark, the row will be highlighted in yellow.  You can mark more than 1 row, and the marked rows do not have to be contiguous.  Unmark the record simply by clicking on a marked row.

2.	Click on the "Mark Record" command button.  All records satisfying the criteria in the text control next to the button will be marked in yellow color.  You can experiment by modifying the selection criteria in the text control.  A sample criteria is displayed in the text control to illustrate the syntax expected.

You can examine all marked records using the BookmarkList property of the database table.

Click on the "SQL" command button.  The grid will display the record set specified by the SQL statement.  You can experiment by modifying the SQL statement to display different record sets in the grid.  A sample SQL statement is displayed in the text control to remind you of the SQL syntax.

To print a report click on the "Print Report" button.  A Crystal Reports preview window will pop up with the current layout and data of the grid.  This preview window will contain only the records and fields in the SQL statement.  Using this feature it is possible to print a variety of reports from a single grid without the use of an RPT file.


MarkGrid Help Index (sample)
 MarkGrid Help Index

  MarkGrid Overview

  Creating the MarkGrid project

 Setting TrueGrid properties

  Setting Data Control properties

  Setting the Crystal VBX properties

  Setting the DatabaseName property in the Form Load event

  Marking records in TrueGrid

  Selecting RecordSource using an SQL statement

Creating the MarkGrid project

Assuming you have installed TrueGrid in C:\TRUEGRID, All source code for the MarkGrid application is included in the C:\TRUEGRID\MARKGRID subdirectory.  The main form contains a Data Controls (Data1), a TrueGrid (Table1), 2 command buttons, 2 text controls, and a Crystal VBX (Report1).  This application requires very little code.  Just set the properties and add code as described in the following sections.

Setting Data Control properties

For Data1, set the following properties:

Caption	Composer Database

RecordSource	composer

The DatabaseName property (which contain the directory where the database resides) of Data1 is not set.  This is because we do not know where you have installed TrueGrid.  Hence we defer setting the DatabaseName properties to the Form_Load event as described in the Setting DatabaseName property in Form_Load section.

Setting TrueGrid properties

Link (bound) Table1 to Data1 by setting the following property:

DataSource	Data1

SelectMode	1 (Enabled)

SelectedBackColor	&H0000FFFF& (yellow)

The SelectMode property of Table1 is set to 1 (Enabled) so that user can mark records on the grid.  See Overview and Marking records in TrueGrid

Table1 is used to display the composer table.  The 4th and 5th fields of the database are the composer's birth and death dates, respectively.  We wish to display the dates in mm/dd/yyyy format (default date format is mm/dd/yy).  We can define the EditMask property at design time using the Layout Editor.  But, instead, we will define the EditMask in the Form_Paint event at run time as follows:

Table1.EditMask(4) = "mm/dd/yyyy"

Table1.EditMask(5) = "mm/dd/yyyy"

Setting the Crystal VBX Properties

Setting up printing from the grid is very easy.  Simply drop a Crystal VBX icon on the from and set the following properties:

ReportSource: 1 - Bound TrueGrid Control

BoundReportHeading: Dynaset Data Report

BoundReportFooter: True

DataSource: Data1

Then in the Print button set the Action property to one (1).  When clicked a Crystal preview window will appear with the currently selected SQL records displayed.

Setting DatabaseName property in the Form Load event

The DatabaseName property of  the Data Controls should be set to the directory name containing the databases.  Assuming you install TrueGrid in C:\TRUEGRID, the databases will be located in the C:\TRUEGRID\LINKGRID subdirectory.  Since you may install TrueGrid in other directories, we will not specific the DatabaseName during Visual Basic design time.  Instead, we use the App.Path property to determine the directory where the databases are stored in the Form_Load event:

Data1.DatabaseName = App.Path & "\markgrid.mdb"

Marking records in TrueGrid

By setting the TrueGrid SelectMode property to 1 (Enabled), user can toggle near the left edge of the grid to mark and unmark a row (record).  You can also mark the records from code as in the Command1_Click event in From1 of the MARKGRID.MAK project:

Dim dClone As Dynaset

Set dClone = Data1.Recordset.Clone

dClone.FindFirst Text1.Text

While Not dClone.NoMatch

    Table1.BookmarkList(Table1.BookmarkCount) = dClone.Bookmark

    dClone.FindNext Text1.Text

Wend

Selecting RecordSource using SQL statement

As you select a record set using a SQL statement, TrueGrid will be notified automatically and refresh itself to display the new record set.  The Command2_Click event in Form1 of the MARKGRID.MAK project selects the record set displayed by the grid:

Data1.RecordSource = Text2.Text

Data1.Refresh


Appointment Book Help Index (sample)
  Appointment Book Help Index

  Appointment Book overview

  How drag-and-drop is implemented

  Changing color attributes

  A look at how the Appointment Book uses callback mode

Appoinment Book Overview

The Appointment Book sample is meant to show you how to incorporate several of the grid's new features into a comprehensive application.  This sample illustrates how to implement a drag-and-drop operation in the grid, how to interactively set the grid's color, and also how to use callback mode.

The program is a simple appointment book.  It allows you to drop in specific types of appointments into time slots on the grid.  Once the appointment is dropped on the grid it is titled according to type and the focus is shifted to the post-it area where you can enter more information about that appointment.

Other features include the ability to rearrange appointments by dragging existing appointments from one location to another,  changing the time in the post-it area and having the appointment automatically moved in the grid, finally, being able to drag an existing appointment into a picture of a trashcan to have it removed from the appointment book.

Drag-and-drop Features

The appointment book sample implements several of the grid's drag-and-drop features.  There are three main events that control the grid's drag-and-drop operation:  DragCell, DragDrop, and DragOver.  The DragCell event is triggered when the user clicks the right mouse button and starts dragging.  In this event we set the grid's RowIndex to the row in which the user initiated dragging, set the DragRow global variable that tracks the row while dragging occurs, set the drag icon and then begin dragging.

In the DragDrop event the user has dropped the object on the grid.  Our job is to determine what they dropped and where they dropped it.  Using the PointX, and PointY, and RowAtPoint we can determine where the object was dropped.  Now if the object is a new appointment we simply set the RowIndex to that Row and update the ApptInfo global array.  If it is an old appointment being moved from another location in the grid then we get the new time and call the ChangeApptTime function.

The DragOver event tracks the movement of any objects which are dragged over it.  Whether it is a new appointment or an old one we move the grid's RowIndex to the position returned by X and Y using PointX, PointY, and RowAtPoint properties.  If the object is leaving the grid then return the RowIndex to where the drag was initiated using the DragRow global variable.

Changing color attributes

This sample uses three of the available color setting capabilities.  The Grid BackColor and ForeColor are of course set by default.  We are however going to override these settings.  In the Form_Load event we set the ColumnBackColor of both of the available columns to green and yellow respectively.  Remember that ColumnBackColor has a higher attribute precedence then the grid's BackColor.

The second capability we are going to use is the FetchAttributes event.  By setting the ColumnCellAttrs property for column two we are causing the FetchAttributes event to be called any time column two(2) needs to repaint itself.  In the FetchAttributes event we are setting the current cell to green and white only if it has an appointment in it.  So we check the text and status of the current cell and if both conditions are met then we set the BgColor and FgColor for that cell.  The other condition covered in the FetchArributes event is the appointment that is being dragged to a new location.  We want to highlight both the old location and the proposed location.  The FetchAttributes event handles the old location by changing the color of the DragRow cell (DragRow is a valid number only while dragging is occurring).

The last color feature we are going to use pertains to the destination cell during the drag operation.  We want the current cell to be blue and white while dragging occurs.  To accomplish this we set the ColumnSetStatusAttr property for the current cell to the new color settings, in the BeginDragMode event.  Now how do we turn it off?  We know that EndDragMode event is called when dragging is over so we simply set the ParamBackColor and ParamForeColor properties to INHERIT_COLOR and then set the ColumnSetStatusAttr property to the current cell again.  This effectively erases the previous condition and returns us to the previous color settings.

Callback mode

When the grid is in callback mode the are two important events that have to be implemented.  The Fetch must contain data to have the grid display data.  If the grid is editable then the Update event needs to pass information back to the storage variable.  In the Form_Load event the grid's Rows property is set and this triggers the Fetch event.  In our case we have provided two arrays, ApptTimes and ApptInfo, to the Fetch event.  If the Col parameter is one then we have it display the time, and if two then display an appointment if one has been entered.  Remember that the grid needs to have a persistent storage mechanism because this event is called in a variety of situations.

In this sample the Update event is not used because the grid's editable property is False.


General Ledger Help Index (sample)
  General Ledger Help Index

  General Ledger Overview

  How to use General Ledger

  How General Ledger works

General Ledger Overview

This sample illustrates an number of important points about how splits can be used effectively, and how several additional features (such as outlining and updated calc columns) can be used.  Keep in mind that we know very little about accounting, so we apologize for any humorous design flaws.

How to use General Ledger

1.	There are both minor and major general ledger accounts.  The minor accounts have a decimal position.  The "Account Name" field is automatically indented for these minor accounts, to give the column an outline appearance.  Notice that TrueGrid will automatically maintain the outline indent level for you.  If you change a GL number from a minor to major number (of vice versa), then indentation changes automatically.  The indentation is a "hard" indent; that is, if you edit the cell, the margin is maintained as well and the user cannot affect the indent margins interactively.

2.	Major GL numbers appear in boldface, while minor numbers appear in a non bold font.

3.	The center split contains several columns pertinent to the account and can be scrolled.  The leftmost split (the GL number) and the rightmost split (the Debit and Credit amounts) are fixed splits, although their columns can be moved and resized.  We have chosen to have the vertical scrollbar attached to the center split.  This may be unorthodox (by default it would be at the far right), but we wanted to illustrate the option.

4.	The Credit and Debit columns are very interesting.  The actual balance is stored in a field called "Balance" and it is stored as a negative or positive number.  The Debit and Credit columns are calculated columns which display the proper value, or Null.  These columns are updatable, though.  If you enter data in the Debit column, the balance will be made positive.  If you enter data in the Credit column, the balance will be made negative.

5.	The tab and arrow keys are set up so that you can tab from split to split or use the arrows to move from split to split.  This gives the grid a good overall feel and makes the fixed columns seem like a part of the total record.

How General Ledger works

Creating this sample requires knowledge of how splits work, so you should review the split properties if you really want to understand this.  Here are the steps to create the application:

1.	Put a TrueGrid on the form, then set the properties that are applied globally.  First, set SplitTabMode to 1 indicating that tabbing between splits was OK.  Then set HorzLines to "1 - single".  also set MarqueeStyle to "Highlight Cell".  Turn off FontBold and set HeadingFontStyle to "2 - Bold" so that only the headings appear in bold.

2.	Now, set SplitPropsGlobal and SplitLocked both to False.  SplitLocked controls whether the split bar appears (it doesn't when locked).  SplitPropsGlobal controls whether changes are made to the current split, or to all splits globally.  Keep in mind that with SplitPropsGlobal, each split has its own set of properties and column configurations so you'll need to be aware of what the current split is.  In the Layout Editor, this is pretty easy, since the current split is the highlighted one.  When you're not in the layout editor, the SplitIndex property is used to indicate which split is being modified.

3.	Next, put the Data Control on the form, set its properties, and set the DataSource for TrueGrid to point to the Data Control.

4.	Then, go into the layout editor and use the default column layout from the database.  Initially, there is only one split, but there is a small split bar at the lower left corner.

5.	Next create two splits by dragging the split bar.  The position of the splits isn't important right now (we'll change that later), but the columns need to be configured first.

6.	First, go to the rightmost split (the Debit/Credit split) and bring up the Column Properties Dialog.  Then create two new columns (for Debit and Credit) and set both of them to calculated columns.  The expression is set to depend upon the ColumnText of the "Balance" column and both are editable.  Note that creating these columns adds them to all splits; we'll hide them in a moment.

7.	Still in the rightmost split, make all columns invisible except Debit and Credit.  These changes apply only to this split.  For the "Balance" column, click "Preserve" so that the hidden column remains as part of the design-time layout.  Normally, if a column is invisible in all splits when you exit design mode, TrueGrid removes the column from the layout to save memory at runtime.

8.	Then, go  to the leftmost split, bring up the Column Properties Dialog and make all columns except the "AccountID" (GL#) invisible.  As you work, chang the heading text and justification styles to the values you want.

9.	Then, go to the center split, bring up the Column Properties Dialog and make the GL#, Balance, and Debit and Credit columns invisible.

10.	Now that the columns within the splits are set-up, exit the Layout Editor to change some of the other characteristics of the splits.

11.	Both the left split (1) and right split (2) should contain only the columns specified and should have no horizontal scrollbar.  First, set SplitIndex to 1, selecting the left split.  Then, change SplitSizeMode to "2 - Number of columns".  When you do this, the other splits instantly disappear, but they'll come back in a moment.  Next, set SplitSize to "1" indicating that only one column is to be displayed at all times.  Then, do the same thing for the rightmost split, except set SplitSize to 2 so that the Debit and Credit columns always fill the split.  Setting SplitSizeMode in this case tells TrueGrid that the split size should conform to exactly the number of columns specified.  Thus, if user's resize the columns, TrueGrid automatically resizes the split to conform to the exact column size.

12.	Next, for each split, set the horizontal and vertical line colors.  Each split has its own seettings for these, so we need to set SplitIndex before changing the colors for each split.  In addition, set SplitLocked to True for each split so that interactive split creation and resizing is disabled.

13.	Now, add the code to implement the Debit/Credit update, as well as code in FetchMargins to control the margins for the AccountName field.

14.	In form load, set up the column attributes.  This is a bit complex, but it's only a few lines of code to tell TrueGrid to do some quite amazing things.  Set a regular expression for the GL# column to "^[0-9]+$", which matches values which contain only numbers and nothing else.  For such cells, specify that the font should be bold so that major GL numbers are always in bold and others are in normal text.

The code in the sample is well-commented and there's very little to look at.  Enjoy.


Drag and Drop Help Index (sample)
  Drag and Drop Help Index

  Drag and Drop overview

  How to use Drag and Drop

  How Drag and Drop works

Drag and Drop overview

This samples covers all the issues that deal with using Drag and Drop in TrueGrid.  This sample shows you how to drag a cell from one grid to another using the grid's built-in drag and drop functions.  Events like DragCell and DragOver and properties like RowAtPoint and PointX are used discussed so that you can add a drag and drop feel to your application.

How to use Drag and Drop sample

Two grids are displayed, each for a different database.  You can drag a name from the Name column in the top grid and drop it into any one of the cells in the bottom grid.  This will put that person's name as the Project Mananger and also replace the phone number for that record to the new Project Manager's phone number.  It's pretty simple, and so is the code.

How Drag and Drop sample works

For the top grid, there is code in the DragCell event which starts the drag.  TrueGrid will automatically detect the beginning of a drag operation, and trigger DragCell to tell your code that a drag is beginning.  Since the drag-from cell doesn't need to be the current cell, code is included to set the current ColumnIndex and RowIndex to the row and column arguments passed to DragCell.  Later, the bottom grid will use the Text property to get the value of the cell which was dragged.

For the bottom grid, there is code in both the DragOver handler and the DragDrop handler.

The DragOver handler is used to change the highlight from a "row marquee" to a cell highlight.  It also uses the ColumnAtPoint and RowAtPoint properties to find out which cell the mouse is pointing to.  It sets ColumnIndex and RowIndex to that cell so that the marquee moves with the mouse.

The DragDrop handler detects the drop.  It simply assigns the Text property of the top grid to the ColumnText property of the bottom grid then tells the Data Control to update the data.  Pretty simple, we think you'll agree.


Dropdown Help Index (sample)
  Dropdown Help Index

  Overview of Dropdown sample

  How Dropdown works

Dropdown Overview

In this sample, the "Au_ID" field of good ol' biblio.mdb is set to pop-up a data dropdown when you edit it.  You can select an author by double-clicking and the data will be updated automatically.  After working through this sample you will be able to link any control to a grid column.  Most of the properties and events relating to cell location and editing are covered in this sample.

How Dropdown works

The RequestEdit event is used to detect an attempt to edit the Au_ID column.  If the user simply begins typing, no drop-down appears and the cell contents are replaced with the typed text.  However, if you click on the cell, the RequestEdit event will pop-up the data dropdown.

The data dropdown is actually another TrueGrid control which is linked to another data control.  Normally, the drop down grid is not visible.  In RequestEdit, the following code is used to display it:

Table2.Top = Table1.CellRectTop + Table1.CellRectHeight

Table2.Left = Table1.CellRectLeft

Table2.Visible = TRUE

Table2.SetFocus

In the above code, Table2 is the dropdown, while Table1 is the table which is being edited.  Both tables were configured at design-time to look right for the task.  Using properties such as CellRectLeft and CellRectTop, you can position controls in almost any conceivable manner relative to the editing cell.

The LostFocus event of Table2 hides the drop down, and the DblClick event of Table2 takes care of updating the cell text in Table1.


Editing Help Index (sample)
  Editing Help Index

  Overview of Editing sample

  How to use Editing sample

Overview of Editing sample

This sample covers a variety of ways in which the programmer can allow the user to enter information into the grid.  Several styles of data entry are included as well as how to implement them.  The first style is using TrueGrid's value list feature to display off and on check boxes in place of database boolean values.  Another method allows you to use radio buttons to select priority.  It also show you how to do a calclated column and display the result as either text or pictures.  This is in addition to using an SQL statement to order the data in the grid.  For more information on value list see the section entitled Introduction to Value lists.

How to use the Editing sample

The EDITING.MAK project illustrates quite a few features which you will find useful for customizing the way editing works.

The sample includes a grid which displays a task list.  The behavior of several of the columns is notable:

1.	Description.  The description column is configured so that any past due items are displayed in red.  This is done by using the FetchAttributes event, which allows you to customize the cell appearance according to almost any conceivable way.  This is the slowest way to control cell color, since TrueGrid needs to ask your Visual Basic program each time it thinks the cell color may need to change.  There are two other ways (using cell status, and using pattern matching on the cell) which are very fast.  However, you will note that the performance is quite good even for this slowest of cases.  The code in FetchAttributes tests the value of the "Past Due" column (which is a calculated column) to determine if the cell should be red.

2.	Past Due.  This column is calculated and determines whether an item is past due.  If you go into the Layout Editor and check the properties for the column, you will see the Visual Basic expression which is used to calculate the value.  If you go into the Field Values Dialog  you will see that the result of the expression is displayed as either a picture or text.

3.	Done.  The done column is a boolean.  You change its value by pressing clicking with the mouse when you're over the column.  This is done by using the Field Values Dialog and checking the cycle on click check box.

4.	Status.  The status column, when edited, pops up a standard VB list box to display a list of choices.  The method used here uses TrueGrid's automatic dropdown combo in the Field Values dialog.  Simply double click on the option you want and the current cell will contain the new value.


Column Summary Sample Help Index (sample)
  Order Entry Summaries Sample Help Index

  Overview of Order Entry Summaries sample

  How to use Order Entry Summaries sample

Overview of Order Entry Summaries sample

This sample is a simple order entry program that calculates an order and each item in that order, taking into account things like % of discount and tax.  This sample also takes advantage of TrueGrid's column summary feature.  Using this feature the grid automatically calculates the number of items in the order as well as sum up the cost of the order.

This sample also allows you to add new records either by using the New Order button, or by pressing the down arrow key on the last row.  Lastly the grid uses a calculated column to calculate the total price of an item in the order taking into account the % discount.

How to use Order Entry Summaries sample

Adding records	If you want to add records in the grid you can do it one of several ways.  Two of the ways demonstrated in this sample are using the data control's AddNew method in the Append event of the grid and in a button.  The Append event is called when the user is on the last row and presses the down arrow key.  The grid will display a blank row that the user can then enter the data into.  If the user does not enter data then the grid will automatically delete the row.  The same holds true if you use the button to add a record.  If no changes are made either in the grid or bound controls the record is automatically removed.

Calculated Columns	The grid uses a calculated column to calculate the price of an individual item in the order.  To do this go into the Column Properties Dialog set the ColumnType to 2 - Calculated.  Then in the expression box put in the following:

(val(ColumnText("Unit Price"))*val(ColumnText("Quantity"))*(1-val(ColumnText("Discount"))))

This will calculate the unit price times the quantity and reduce it by the discount and display the result.  This feature allows you to maintain less data in the database and still give you freedom from maintaining the calculations yourself.

Summing Columns	One aspect of the column summary feature is it allows you to automatically maintain the sum of the contents of a column.  To enable this feature set the ColumnSumEnable  property to True.  To display the result use the ColumnSumChange event and print it to a text box, label, or whatever.

Complex Column Summation	Getting the sum of a column may not be enough.  You may want to use that value for other calculations.  Column Summaries sample also has an example of this.  If you look at the ColumnSumChange event you will see that if the column sum changes for the Total column a function is called: RecalcTotal.  This function calculates a grand total using a tax percentage specified by the user.


In-Cell Graphic Sample Help Index (sample)
  In-Cell Grahpic Sample Help Index

  Overview of the In-Cell Graphic sample

  How to use the In-Cell Graphic sample

Overview of the In-Cell Graphic sample

This sample displays a collection of flags instead of the standard 'country name''.  The grid even goes a step beyond this by allowing the user to choose the country name from a drop-down list box when they click in the cell.  After the user chooses a the value the grid populates it with the appropriate country's flag.  To implement this feature we used a standard VB list box.  You could just as easily use a 3rd party combo or list box.  This is a very powerful feature because using this method you could easly pop-up any control on top of the current cell to assist in data entry.

This sample also illustrates how to set up calculated column to display either picture or text depending on the value.  Using the Field Values Dialog you can have the grid substitute cryptic database values with pictures, descriptive text, or whatever you can dream up.

How to use the In-Cell Graphic sample

Value lists	To set up this example we used the flags from the Visual Basic directory.  Bring up the layout editor for the flags column and then click on the Value List... option.  When the field values dialog appears you should see the Column name in the dialog caption and a grid with just a data column.  Enter in all the countries in the data column, click on the Translate Values check box and then populate the right hand column by selecting a cell and clicking the Picture button.  That's all there is to it, you now have a country value list.  Next we will set up the drop-down list box.

Automatic Drop-down	To set up a drop-down list box you need to draw a standard list box on the form somewhere and change its Visible property to False.  Next in form load put the code in to add all the countries names to the list.  In the Form Load you can also set the ColumnButton property to True so that when that column is current a drop-down button will appear in the upper right hand corner of the grid' current cell.  In the Click Button event put the following code:

If Table1.ColumnName(Table1.ColumnIndex) = "Flag" Then

Status = Status Xor True    ' Toggle between true and false

If Status Then

List1.Left = Table1.CellRectLeft

List1.Top = Table1.CellRectTop + Table1.CellRectHeight

List1.Visible = True

List1.SetFocus

Else

List1.Visible = False

Status = Status Xor True

End If

End If

This will pop the list box right underneath the current cell.  The rest you handle in the list box:

Table1.ColumnText(TgFindColumn(Table1, "Country")) = List1.List(List1.ListIndex)

List1.Visible = False

Calculated Columns	This column is calculated and determines whether the current account deserves a smiley face.  If you go into the Layout Editor and check the properties for the column, you will see the Visual Basic expression which is used to calculate the value.  If you go into the Field Values Dialog  you will see that the result of the expression is displayed as either a picture or text.


 Callback Sample Help Index

  Overview of the Callback sample

  How to use the Callback sample

Overview of the Callback sample

This sample provides an introduction on how to use the grid in callback mode.  First and foremost, this grid is not like GRID.VBX in Visual Basic 3.0.  The fundamental difference is that TrueGrid does not store data and therefore you do not have functions like AddItem and RemoveItem.  In callback mode, also called application mode, you supply the data source and the grid displays it.

TrueGrid acts as a window on the data that you manage.  It does not store values, it merely displays existing values from pre-defined data sources, whether that be an array, multiple arrays, a random access file, or a database not supported via Visual Basic Data Access.  This simplifies how you use TrueGrid with your data.

Using the grid in callback mode it is possible to look at a non-database file, a database not supported by Visual Basics Data Access, an array, several arrays, and even calculated values.  Below we will describe the two main mechanisms for displaying and updating data in the grid.

How to use the Callback sample

The main mechanism for the grid's display is the Fetch event.  This event is called automatically when the grid needs to know the contents of a cell.  Once your code is in place to display a value the grid automatically handles looking up that value.  In this sample we are looking at an array so the Fetch event is setup up to read the array:

Global GridData(Row, Col)

Sub Table1_Fetch (Row As Long, Col As Integer, Value As String)

    'Set the display of the grid to the

    'contents of the GridData array

    Value = GridData(Row, Col)

End Sub

You can see that we simply set the Value parameter to the array with the Row and Col parameters as its indices.  Remember that the Fetch event is automatically called for each displayed cell and therefore you do not need to loop through the event or directly call Fetch.  The grid will simply wants you to set the Value based on the Row and Col parameter that it provides.

The only other issue in displaying values in the grid is making sure that you have both the Rows and Columns for the grid defined.  Normally you will setup the grid's columns at design time, although you do not have to.  You will also need to set the Rows property, usually in the Form_Load to the number of rows you want the grid to be able to display.  Remember that this setting does not mean that the grid will Fetch all these rows as soon as you set this property, it will only fetch the displayed rows and columns.  You can also change the rows property dynamically throughout the application and the grid will automatically refresh with the new information.  Remember to resize your array to accommodate the new dimensions of the grid.

If you want the user to be able to update data then you simply reverse the code from the Fetch event.  The Update event is called anytime the user has made changes to the grid directly by typing in the cells or by the programmer when setting the ColumnText property. Our sample's Update event looks like this:

Sub Table1_Update (Row As Long, Col As Integer, Value As String)

    'Updates the GridData array with the new value

    'passed in by the Value parameter, usually

    'upon completion of data entry

    GridData(Row, Col) = Value

End Sub

As you can see all I did was reverse the assignment so that the Array is now being set by the new Value that the grid is passing back.  If you need to validate the data we suggest doing this in the grids Validate event.

That's all it takes!  Using the grid in this mode you still have access to all its features and now you are not limited to 64K of data like you are in GRID.VBX.  This example is a very simple introduction and its main purpose is to describe how the callback mode works.  If you want to see more in-depth examples look at the dBASE Table, Appointment Book, and Table View samples.


View Table Sample Help Index
 Table View Sample Help Index

  Overview of the Table View sample

  How to use the Table View sample

Overview of the Table View sample

The Table View sample attaches a TrueGrid to a Visual Basic Table object.  Using the grid in callback mode and some simple functions you can view a database without the use of the Data Control.  One of the main limitations of using the Data Control supplied with Visual Basic 3.0 is its inability ot take advantage of existing indexes.  This sample will allow you to overcome that limitation.

Not only can you attach the grid to a VB table object but you can also attach it to a dynaset, snapshot, querydef or any other object that supports a few simple navigation functions.  All the functions for this sample are modular and can be rewritten to work with other VB objects or even 3rd party libraries like Q+E Lib, VB/ISAM, or CodeBase.  Simply rewrite the Open and the MoveToRow functions using your database library functions and presto, the grid is attached to your database.

How to use the Table View sample

The Table View sample consists of three major sections.  Setting up the grid, fetching data for the grid, and updating the database from the grid.  The first part, setting up the grid, will probably vary more than any other section depending on what type of database library you are using. The first two functions OpenDb and OpenTb are pretty self explanatory.  One opens the database and the other opens a table in that database.  If your database is not setup like this and you don't have tables within your database (e.g. dBASE) then you can comment out one of the functions.  The important point is that a global object is declared and points to the database (or table).

Next the EndRow variable and table Rows property are set.  They are set to the MAXROW global constant.  This value should approximate the largest size that the database could ever be.  Setting it too small is not necessarily harmful or dangerous but it may impede performance intially or at some unexpected point.

The CheckForIndexes function looks at the Table object to see if it has any indexes attached to it.  If it does the grid adds a menu item and the list of index titles.  Choosing one of those values will re-order the data using that index.  If your database library does not support this type of functionality then you can simply omit this. The last section of the Form_Load is setting up the field names, column widths and sizes.  The FieldLayout function loops through the Table object getting fieldnames and their data types.  Using these it sets up a default layout.  You may choose to setup your grid at design time and again you can just omit this function.

The second part of this sample involves displaying the data.  A function called MoveToRow enables the grid to navigate through the database.  The Fetch event calls MoveToRow, if it succeeds then grid displays the contents of the current field into the current cell, if it fails then it displays an error message to that effect.  This will happen only in rare cases and you will see why when we look at the CheckRows event.

Before the Fetch event is called the CheckRows event must first be called to determine if it is ok to have Fetch called for the new set of rows about to be displayed.  The CheckRows event contains two parameters, RequestRows and CurRows.  Using RequestRows the grid determines whether or not it can display the information requested by the last user action (e.g. page up, scrolling, etc).  The RequestRows will be the value for the highest row number to be displayed by that action.  We send the RequestRows value to the MoveToRow function. If MoveToRow fails with that value then we know that we have reached the end of the database and that we need to reset the overall number of rows.  The value returned by MoveToRow in this case will be the total number of rows currently in the table.  We then set CurRows to this value to prevent the grid from accidentally going beyond the end of the database.  CurRows is the equivalent of the Rows property and can only be set within the CheckRows event.

The MoveToRow function looks complicated but when you look closer it's actually not too difficult to understand.  It is divided up into three major section and two of those sections are divided up into two more.  The row we need to move to could either be the current row, a row before the one we are currently on, or a row after the one we are currently on.  Depending on that result we go to a second level or exit.  If we are already on the correct row then we just exit the routine, if we need to move forward then we go to the second level.  If we are moving forward we check to see which is closer; the difference between the new row and current row, or the new row and the end of the database.  From that result we determine the quickest way to get to the new location.  If we are moving backwards we pretty much do the reverse and either move from the beginning of the file to the new location or from the current location to the new one.

Once you have the MoveToRow function written everything else is easy.  The last part of this sample involves enabling the user to update the data.  Again we use the MoveToRow function to postion us to the correct row.  Once there we update the field in the database that corresponds to the cell that the user updated in the grid.