Forum > Beginners

TStringGrid : Conflict between "OnEditingDone" and "Columns.Clear"

(1/4) > >>

Nel_Fie:
DISCLAIMER: I'm a self-taught hobbyist with no formal background in programming, and while I've already made a lot of progress with Free Pascal and Lazarus, I still have a lot of blind spots. Please use simple terms and explain steps in details even if they seem completely obvious to you.

I've run into an issue with a TStringGrid component: my "OnEditingDone" event has a handler to process any changes made - which in turn calls a more general procedure which updates the whole grid from scratch. As part of this latter update, the whole grid is cleared with the Columns.Clear method.

However, this frequently causes an error, which (according to the call stack) starts in "grids.pas", goes to "control.inc" line 616 (within the "EDITINGDONE" function in both cases) then over to TStringList itself in "stringl.inc" - with not immediately traceable cause in my own code:

--- Quote ---Project [NAME] raised exception class 'EStringListError' with message:
List index (5) out of bounds
--- End quote ---

Now, as far as I can tell, based on the description of TGridColumns.Clear the problem might be due to a conflict between the fact that I'm calling "Clear" from within "OnEditingDone"s handler, while "Clear" itself starts an updating process that actively suppresses notification events, conflicting with ongoing handlers in the process.

The solution that seems the most immediately obvious to me would be to find a way to delay the update procedure that contains the "Clear" process in a separate thread so that the handler for "OnEditingDone" has time to end, but before I try this (and potentially waste more time) I wanted to know if there was a better/simpler/"canonically correct" solution to this problem.

I can provide more details and code if you ask, but the project itself is already close to 2000 lines long with a lot of content entirely extraneous to this issue - and between that and the fact that the call stack was no help it took me a week to even find the culprit in the first place. I'll rely on you to tell me how much more information is needed.

Zvoni:
Why are you removing all columns at all?
The call to "Clear" removes all columns from the Grid, and then you have to repopulate everything anew, just to get an "Update" of the Grid?
My guess for your Error is you're trying to access a column which doesn't exist

rvk:

--- Quote from: Nel_Fie on May 15, 2023, 10:20:23 am ---The solution that seems the most immediately obvious to me would be to find a way to delay the update procedure that contains the "Clear" process in a separate thread so that the handler for "OnEditingDone" has time to end, but before I try this (and potentially waste more time) I wanted to know if there was a better/simpler/"canonically correct" solution to this problem.
--- End quote ---
Not judging the reason you call TGrid.Columns.Clear inside OnEditingDone (you just should do it there) you could do a PostMessage to the form (if on Windows). That PostMessage-handler is then handled in the Queue and is executed after the OnEditingDone.


--- Quote from: Nel_Fie on May 15, 2023, 10:20:23 am ---I can provide more details and code if you ask, but the project itself is already close to 2000 lines long with a lot of content entirely extraneous to this issue - and between that and the fact that the call stack was no help it took me a week to even find the culprit in the first place. I'll rely on you to tell me how much more information is needed.

--- End quote ---
You could just explain the reason behind the Columns.Clear decision. It might not be needed if you can just adjust the Columns (and keeping them in place) instead of deleting then and rebuilding them. And after the Columns.Clear, where are you adding them again?

Zvoni:

--- Quote from: rvk on May 15, 2023, 11:25:05 am ---You could just explain the reason behind the Columns.Clear decision. It might not be needed if you can just adjust the Columns (and keeping them in place) instead of deleting then and rebuilding them. And after the Columns.Clear, where are you adding them again?

--- End quote ---
That's exactly my point.
He's editing CONTENT of the StringGrid.
As far as i understood, the number of columns and rows stays the same, so there is no reason to empty out the stringgrid completely, just to rebuild everything again.

Maybe OP should take a look at the "Clean"-method

Nel_Fie:
Thank you both Zvoni and rvk for the swift replies. Also thank you for the idea of using PostMessage - I'll give it a try when I get the chance, although it would be an advantage to keep the tool I'm trying to code portable to other systems.

And my apologies for not clarifying why I used "Clear".
The reason is that the tool I'm working on is intended to create, edit and display a large amount of multi-dimensional pieces of data stored in a JSON file - each dimension being represented as a column. On one hand there is a whole filtering system for the user to restrict the display to a specific subset of the data based on the dimensions selected by the user (thus which columns are needed can change with a single click from the user), but also to create, delete or rename dimensions very easily (thus again changing the amount of columns needed as well as the column names).

So, between the fact that the columns needed can change at the drop of a hat (i.e. they might only need hiding for a few seconds, but might also warrant deletion since the dimension they represent was just deleted by the user, and I'd have to track "hiding" and "deleting" separately), but also that some of them are subdimensional (e.g. imagine two dimensions called "red", but one is a child of "colours" whereas the other is a child of "apples". I'd have to track which column called "red" belongs to which larger set) - so it simply takes much less code to rebuild the grid from scratch than trying to manage the existing ones and sort out which need showing, hiding, deleting or creating.

That said, if TStringGrid is not intended for this high-frequency clearing I can write the needed code to keep track of the columns instead, but it would likely be a lot of work.

Navigation

[0] Message Index

[#] Next page

Go to full version