0

I have a stringgrid that has been drawn via complex DrawCell code. It has different font colors, brush colors, alignment etc...

I'm now writing code that exports the contents of the stringgrid. Of course I could use the underlying list and replicate all the formatting and filtering rules used when drawing the grid. But the grid is already filtered & formatted and I'd like to avoid replicating all that code if possible.

So, how can I get the canvas.font.color of a specific TStringGrid cell?

Thanks in advance :)

MarkW
  • 61
  • 7
  • 3
    You can't, because the Font.Color only exists when the cell is being drawn. If you need to be able to access that information, you'll need to store it when the cell is being drawn. – Ken White Jul 06 '17 at 01:42
  • [This answer](https://stackoverflow.com/a/9684956/62576) demonstrates one way to store that information using the `Objects` array of the cells. It has some Lazarus-specific code mentioned, but you can safely ignore that to get the gist of a possible solution. – Ken White Jul 06 '17 at 01:54
  • I came back to update my post when I realised that no Cells strings are available when the grid is painted via DrawCell. Thanks Ken for the tip. I'll look at storing cell content and formatting data in an object associated with each cell. Cheers! – MarkW Jul 06 '17 at 02:15
  • The link I posted shows some pretty good code that should get you started. It's not my answer, but it's pretty good code. :-) – Ken White Jul 06 '17 at 02:17
  • Thanks Ken. Yep - as far as code goes, it's stellar :) – MarkW Jul 06 '17 at 23:40
  • However - I now have a new problem. When I export from the grid, I'm only getting the rows that are actually visible in the grid. This makes sense as the grid is drawn on-demand in the DrawCell method. Is there a way, in code, to force the entire grid to be populated? If I **manually** scroll to the end of the grid, then do my export, all is good. I've done some googling and can't find a way to force-load the entire grid :( – MarkW Jul 06 '17 at 23:56
  • The grid's RowCount reflects the total number of rows, which is good. But the Object property of cells in rows beyond what is visible in the grid is nil, which is bad... – MarkW Jul 07 '17 at 00:19
  • The grid only draws cells that are visible. If the cell isn't seen, there is no point in having drawn it; it's a waste of CPU cycles, and Windows won't paint anything that isn't capable of being seen. (I think your goal is a lost cause, BTW. You have the logic that is used to determine the color of the cell, so you don't really need to store the color values. Just save the data. When it's loaded again, the grid's paint logic will color it again using the same code that drew it in the first place.) – Ken White Jul 07 '17 at 00:22
  • Thanks Ken. I'm beginning to feel the same way re lost cause. >>You have the logic that is used to determine the color of the cell, so you don't really need to store the color values. Just save the data. Yes and no. The rules around selecting what rows to show from the underlying TList, the content/text of the cell, its color and alignment are all known in the DrawCell code. I could export direct from the underlying TList data, but then I'd have to replicate all the display logic again which is what I was trying to avoid. – MarkW Jul 07 '17 at 00:33
  • Why do you have to replicate it again? You have the values, and the logic ran when they were added to the grid in the first place. If you save the values and then reload them, they'll automatically run through the same drawing logic again (as they're drawn when being reloaded). Your data are the values that are provided to the drawing logic; it doesn't matter if they're being loaded for the first time or the second or the 30th; the drawing logic remains the same. – Ken White Jul 07 '17 at 00:43
  • Because the rules re selection, text manipulation, color and alignment from the underlying TList are in just one place at the moment. The DrawCell event. Now, in a completely different part of my program, I need to export the data **as it exists in the grid**, not as it exists in the TList. – MarkW Jul 07 '17 at 02:08
  • I *am* saving the cell content and formatting rules - in an object associated with the cell. As we know, the DrawCell event only gets fired on-demand to fill the visible cells in the grid. So unless I manually scroll through the grid to the bottom, I won't have saved all the data I need to export. I guess I'm not following your implication that the Drawing Logic in the DrawCell event can help me when it comes time to export the data. – MarkW Jul 07 '17 at 02:08
  • You're missing the fact you don't need to export the drawing information in order to export the data. Where are you going to use it other than in the stringgrid itself? You only need to export *data*, not appearance. (Or you have requirements that you've not mentioned here. The font information isn't going to help you if you're drawing outside Delphi.) – Ken White Jul 07 '17 at 02:12
  • I am exporting to Excel. I do need to export 'appearance'. The requirement is for an Excel cell to have the same formatting as what the user sees in the equivalent grid cell. Alignment and font color in particular. But let's put the issue of formatting to one side. Original question: How to get at the text of a stringgrid cell when the stringgrid is populated via DrawCell? Answer: You can't. That data is not persistent. Put the text in an object that can be set for each cell. – MarkW Jul 07 '17 at 02:45
  • Next Question: When I iterate over the stringgrid to do my export, I'm (understandably) only getting the data that's visible in the grid at the time. Is there a way to force-load the grid so that all the cell objects are set? Answer: ? – MarkW Jul 07 '17 at 02:46
  • Not the way the site works. If you have a new (and different) question, create a new post and ask it. Provide the details that you've not provided before this second, which is the requirement to export data and formatting to Excel. Comments are not the place to ask an entirely different question than what you asked in the question itself and is much more broad in scope. (But answer; you can't access drawing information without drawing the cell, and there is no way to say *Draw all the cells in advance of actually needing to draw them*. Don't require visualizing data not needing to appear.) – Ken White Jul 07 '17 at 02:51
  • 1
    Thanks Ken. I was aware I was on thin ice when I asked the follow up question, but we seemed to be going so well :) – MarkW Jul 07 '17 at 03:19

0 Answers0