In all of my Delphi programs - until recently - all the DBGrids have been
read only: the data displayed is retrieved by a query, and if I want to edit
any of the data, a separate 'edit' dialog box is opened with the row's data
displayed. This is something that I have been doing ever since I was
introduced to Delphi over 20 years ago and there are (at least) two reasons
for doing so. The first is that almost all of the queries that are displayed
are not 'live queries' (I think that's the term) as the data displayed comes
from more than one table. The second reason is that many of the fields
display data that come from lookup tables.
That's probably not very clear, so I'll use the example on which I was
working today: a list of contact people for a given customer. The query
itself involves two tables: contacts and a junction table between the
contacts and customers (a contact person can be connected to more than one
customer; a customer can have more than one contact). Such a query by
default is not 'live'. I could have had a field that defines the
type of contact, e.g. one who deals with the financial side, one who
receives reports, etc, where these values would be in another table. As it
happens, one contact can have more than one role, so there is no type field;
instead there are several flags indicating whether the contact is financial,
receives reports, etc.
Those flag fields are now editable in situ within the grid;
one doesn't have to execute the separate 'edit' dialog box in order to
change their value. How did I do this?
-
The grid now has the dgEditing flag set in its options property.
-
On the grid, I right clicked, entered the 'columns editor' and added all
the columns. These come from the query that is linked to the grid so
there's no need to add them manually.
-
All of the columns were marked as read-only = true; some of them were
marked as visible = false.
-
The fields that I wanted to be editable were marked as read-only = false.
I naively thought that I need do no more, but there was one more critical
step that needed to be taken (ironically, I had done this in the blog
manager program a few weeks ago, but there I didn't know about the grid's columns editor, so all the fields are editable; I trust myself only to edit one field). I added an 'update' query that updates the
flags' value in the underlying table (contact2cust); this query is executed
in the datasource's OnUpdateData method. Doing so turns the temporary
change (stored in the clientdataset) into a permanent one (stored in the
database). Funnily enough, I had a similar situation in Priority a few days
ago: a change would be visible but would not be saved.
The flags are shown as checkboxes drawn on the grid, but when they are
edited, their real nature is disclosed - they have one of the values 0 or 1.
The user has to enter the appropriate value in order to change the state of
the checkbox. Of course, this wouldn't be a problem if a normal text or
integer field were involved.
A challenge for myself: how to allow editing a field in situ when
the value has to come from a lookup table. I remember seeing a long time ago
code that allows one to draw a combobox in a grid, so that will be the
starting point. I don't have any need for this at the moment so I'm not
going to devote any time to this.