Ove Halseth
Ove Halseth

Reputation: 461

Set style in cxGrid based on data from all rows

I have a few grids where users enters from-to dates, and would like to set background colour on rows with date-interval that overlap other rows date-interval.

Now I'm using oncalc event on the dataset to set an overlap-flag, but it is a slow solution, and I like to know if it's solvable in cxGrid instead.

Ove B-)

Upvotes: 1

Views: 1586

Answers (3)

Ove Halseth
Ove Halseth

Reputation: 461

I came closest to a solution with @Rigotti's code. But I found no way to manage OnCalc, OnDataChange and OnGetContentStyle. It triggered way to much.

We switched to FireDAC not long ago, and I was not aware that it let you update the underlying table even if the query it self is not updateable. So I calculated the fields in sql and did not need the OnCalc.

Upvotes: 0

MartynA
MartynA

Reputation: 30745

I think you should be able to do this in a fairly straightfoward manner. The fact that the cxGrid can do grouping of data rows and can be switched into and out of grouping mode shows that once the grid has loaded the dataset, it has all the data necessary available to group, ungroup and sort the rows in the grid without having to re-traverse the related dataset. The data is accessible via the Values property of the DBTableView's DataController.

You can access the data rows in a DBTableView in the grid via the Values property of its associated DataController (see other answer or the cxGrid's Online Help) as if it were a two-dimensional array or matrix - the first dimension is the rows of the grid and the second, the index of one of the column values of the grid.

How I would attempt your task would be to

  • Add an fkInternalCalc flag field to the dataset to indicate how the row should be colored. There is on need to set its value in the OnCalcFields event, nor do anything else in OnCalcFields. The reason for including this calculated field is just that it's an easy way of having a Values[] value for it without getting involved in "unbound" grid columns.

  • Once the data is loaded into the grid, process it as a 2D array to work out which rows need to be specially colored and set the Values[entry] for the calculated field

  • Use the DBTableView's OnCustomDrawCell event to color the cells as you require.

This may require a bit of fine-tuning of its implementation details but I think that in principle it should work.

NB: This will only work if the DataController's IsGridMode property is set to False. If it is set to True, only a sub-set of the dataset's rows are loaded at any one time, so the grid will not group and you will not be able to process the whole of the dataset using its 2D representation in the the DataController's Values property.

Upvotes: 2

Rigotti
Rigotti

Reputation: 98

I don't know in which moment would you like to do this verification, but you can iterate through the grid dataset to check if there is any record that overlaps and maybe use a invisible unbound column as a flag.

var
I, ARecordIndex: Integer;
begin
    for I := 0 to cxGrid1DBTableView1.DataController.FilteredRecordCount - 1 do
    begin
        ARecordIndex := cxGrid1DBTableView1.DataController.FilteredRecordIndex[I];
        if (Pos('ame2', cxGrid1DBTableView1.DataController.Values[ARecordIndex, cxGrid1DBTableView1Name.Index]) <> 0) then
        cxGrid1DBTableView1.DataController.FocusedRecordIndex := ARecordIndex;
    end;
end;

Upvotes: 1

Related Questions