As you certainly know, when you click on a TStringGrid, the selected cell is barely visible. That's why I would like to change its colour from white to blue when I click on it. The colour should then become white again when the focus is set on a different object. Do you know how to do it? Thanks in advance. I've used a TStringGrid in my application and have written the required code for OnDrawCell event to change its default appearance. All the things are working properly, but there is a small bug in its appearance while moving through rows by keyboard. Note that the goRowSelect is set to true and the following code is used inside the OnDrawCell.
I have a TStringGrid object on a form which has 1 FixedCol and 1 FixedRow. I want to be able to select an entire row on the object when the user clicks on any cell within that row. This selection must also be visible to the user (I want the row to change colour).
EDIT: Have put goRowSelect in options on the object. Is there now a way to select the row on the click of one of the cells in the fixed column?
SerythSeryth
2 Answers
If you enable the option
goFixedColClick
of the string grid you can then use the OnFixedCellClick
event to determine which row to select. You can then set StringGrid1.Selection := TGridRect(Rect(0, Row, n, Row));
where Row is the row clicked and n is the width of your StringGrid.Andy_DAndy_D
In order highlight entire row when ever the user clicks on any cell in that row, set the following StringGrid properties.
In design time: Go to options property and check the following sub-properties.
To achieve this at run time,
Hari Babu MandalaHari Babu Mandala
Not the answer you're looking for? Browse other questions tagged delphitstringgrid or ask your own question.
Question:
Can anyone point to an article or code samples anywhere on how to provide BOTH editing AND range selection in a TStringGrid?
Yes, I KNOW there are third-party grids that do this, but it's frustrating that the built-in grid lacks this basic capability.
Background:
It's pretty normal to expect to be able to both edit a cell in a grid, and also to select a range of cells such as for a Copy operation.
As delivered, TStringGrid doesn't do that. It's either/or. In fact, the docs tell us about the grid Options, 'When goEditing is included in Options, goRangeSelect has no effect'.
However, it looks like it may be possible to do editing and rangeselects in a TStringGrid anyway!!! Through careful use of the mousedown, mouseup, selectcell and exit events, you can get dang close by switching editing elements on and off at the right times. But I still don't have it perfect, and that only covers mouse use, not keyboard changes.
Kevin KillionKevin Killion
2 Answers
I have not used the
TStringGrid
for this, so I can't provide a specific answer. But am I right in assuming you can manually (in code) start a cell being edited? That link implies it is possible even if the grid doesn't have goEditing
included in its Options
. (See below to work around this if this is not true.)If so, I'd suggest the following approach:
Combined selection and edit behaviour
I find this is a good, Windows-standard-behaviour sort of approach:
- Leave the grid in selection mode, so mouse and keyboard interaction selects cells
- Trigger a cell being edited yourself, based on certain criteria (I think you are on the way to doing this from what you said in your last paragraph.) There are common ways to trigger editing, and the following criteria are what my programs follow when they do something similar with other controls:
- Selection is normal. Ie, click to select, click and drag to multi-select, use the keyboard arrows and Shift or Control to select, etc.
- A cell enters edit mode when either:
- A cell is selected and the user presses
Enter
orF2
(F2
is the standard 'Rename' or 'Edit' shortcut, which works in a number of programs) - The user 'slow-double-clicks' on a cell - ie, slow-double-clicks to select and edit, or clicks again, after a pause, on an already-selected cell. This mimics Explorer's behaviour, where if a file is selected and you later click on it, it enters the inline edit/rename mode. To implement this, record when a cell was last clicked (and selected.) If it is clicked again, and if the time is greater than
GetDoubleClickTime
then they have clicked twice, slowly, and enter edit mode. This allows you to distinguish between the first click to select, a double-click (to perform some kind of action), and a slow second click, to enter edit mode.I also tend to check the mouse position, so that if an object is slow-double-clicked and it wasn't first selected (ie, this both selects the object and then enters edit mode) I verify the mouse hasn't moved very much. I useGetSystemMetrics
to find the double-click distance, and check that the slow double click was within this box. (Because it's not a true doubleclick, I actually check the distance times 2. My action code is:const int iMAX_MOVE_AMOUNT = ::GetSystemMetrics(SM_CYDOUBLECLK) * 2;
(sorry, C++ not Delphi, but should be convertable easily enough!)but I'm actually not certain if this is completely and utterly 100% to Windows guidelines. In practice users find it works as they expect, though.)
That should let you change between selecting and editing at the appropriate times with both the keyboard and the mouse.
Miscellaneous thoughts
You may find some of this is cleaner and easier to implement by subclassing
TStringGrid
and creating a new component. That will allow you to implement this in normal code and override the inbuilt behaviour (rather than event handlers) while keeping it invisible to the form code. It will also give you lower-level access to the mouse events or Windows messages than are exposed simply through events such as OnMouseDown
. Finally, if there are problems with showing the editor when goEditing
is included in Options
, this will allow you to change that behaviour. You could also add your own events if you want your code to respond to certain things happening, such as creating an OnBeginEdit
event, say.Creating your own components is normally regarded as an advanced Delphi topic, but it's actually remarkably easy once you know how!This site has a few good topics that will introduce you to the subject in general, and if you go this route and encounter problems, Stack Overflow is of course a good place to ask questions :) The Embarcadero Delphi » VCL » Writing Components newsgroup / forum is also an excellent resource, in fact possibly even better than SO for this specific topic.
Hope that helps!
DavidDavid
Yes it's old post, but the problem still exist on Delphi XE3. To manage this feature I used next 'trick' in SelectCell procedure :
if (ARow = StringGridParam.Row) thenbegin StringGridParam.Options:= StringGridParam.Options + [goEditing] - [goRowSelect];end else begin StringGridParam.Options:= StringGridParam.Options + [goRowSelect] - [goEditing];end;
SuperbebertSuperbebert