I am trying to make use of the Objects property of the Stringgrid inside my descendant and I think I am doing something wrong. So, I created a simple class for use in my StringGrid cells, something like:
type
TKind = (tkNone,tkStart, tkEnd, tkMiddle);
TMyCell = class(TObject)
private
FKind:string; // TKind: start, middle, end, none
FOfType:string; // new, registered, paid, over, none
FActualDate:TDate;
FTheText:string; // if you want to show a text in it
FIsWeekend:Boolean;
function IsItWeekend(dt:Tdate):boolean;
procedure setKind(s:string);
{ Private declarations }
protected
{ Protected declarations }
public
constructor Create;
property Kind:string read FKind write setKind;
property OfType:string read FOfType write FOfType;
property ActualDate:TDate read FActualDate write FActualDate;
property TheText:string read FTheText write FTheText;
property IsWeekend:Boolean read FIsWeekend write FIsWeekend default false;
{ Public declarations }
published
{ Published declarations }
end;
implementation
procedure TMyCell.setKind(s:string);
begin
FKind:=s;
end;
function TMyCell.IsItWeekend(dt:Tdate):boolean;
begin
if (DayOfTheWeek(dt)=6) or (DayOfTheWeek(dt)=7) then IsItWeekend:=true else IsItWeekend:=false;
end;
constructor TMyCell.Create;
var
i:integer;
a,l,z:word;
dt:TDate;
begin
FKind:='none';
FOfType:='none';
FActualDate:=now;
FTheText:='';
FIsWeekend:=IsItWeekend(FActualDate);
end;
then, in my StringGrid descendant (TMyGrid), I do the following:
TMyGrid = class(TStringGrid)
private
FStartSelection:integer;
FFixedColor:TColor;
FRowCount:integer;
...
published
property ColCount;
property RowCount;
...
constructor TMyGrid.Create(AOwner: TComponent);
var
i:integer;
a,l,z:word;
dt:TDate;
j: Integer;
myCell:TMyCell;
begin
inherited;
...// different settings
RowCount:=5;
for i := 0 to colCount-1 do
for j := 0 to RowCount-1 do
begin
Objects[i, j] := TMyCell.Create;
end;
end;
destructor TMyGrid.Destroy;
var
i,j:integer;
begin
for i := 0 to colCount-1 do
for j := 0 to RowCount-1 do
begin
TMyCell(Objects[i, j]).Free;
end;
inherited;
end;
... // other stuff
procedure Register;
begin
RegisterComponents('mygrid', [TMyGrid]);
end;
The problem is I don't know how do I tell my control that there are more rows when the developer changes the RowCount in the objectInspector before running the app. So I drop my StrinGrid descendant on a form, and set the rowCount to 10. But my StringGrid does not have Objects created for the new rows, So the cells on ARow=5->9 do not have objects created... because in OnCreate I only set the initial value of the RowCount to 5 and create objects for i:=0 to RowCount-1.
Is there an event or method where I can tell the StringGrid to create the Objects after the developer changes the rowCount in ObjectInspector?
I am sure that this is my problem because, using the above code, when I drop my stringGrid on a form and set it's rowCount (design time or runtime) to 10 then I want to assign a value to Kind property of a cell that is on a Row>4 I get an AccessViolation, but if I do that for a row that is <= 4 the assignment works just fine.
I found something that should help here: http://embarcadero.newsgroups.archived.at/public.delphi.ide/200904/0904193279.html but I do not know how and where to place this code in my StringGrid descendant class so it would get called when RowCount is changed at designtime/runtime
EDIT
After reading your comments I tried your idea (that seemed to work) to override the SizeChanged (I did not know that method existed, must have skipped it when I serached before). Anyway, I added this code to my class:
TMyGrid = class(TStringGrid)
private
...
procedure SizeChanged(OldColCount, OldRowCount: Longint); override;
procedure UpdateGridDimensions(NewColCount, NewRowCount: Integer);
...
procedure TMyGrid.SizeChanged(OldColCount, OldRowCount: Longint);
begin
inherited;
if (OldRowCount<>FRowCount)or(OldColCount<>ColCount) then
UpdateGridDimensions(ColCount, FRowCount);
end;
procedure TMyGrid.UpdateGridDimensions(NewColCount, NewRowCount: Integer);
var
C, R: Integer;
Old: Integer;
begin
if NewColCount <> ColCount then
begin
if NewColCount < ColCount then
begin
for R := 0 to RowCount-1 do
begin
for C := ColCount-1 downto NewColCount do
Objects[C, R].Free;
end;
end;
Old := ColCount;
ColCount := NewColCount;
if NewColCount > Old then
begin
for R := 0 to RowCount-1 do
begin
for C := Old to NewColCount-1 do
Objects[C, R] := TMyCell.Create;
end;
end;
end;
if NewRowCount <> RowCount then
begin
if NewRowCount < RowCount then
begin
for C := 0 to ColCount-1 do
begin
for R := RowCount-1 downto NewRowCount do
Objects[C, R].Free;
end;
end;
Old := RowCount;
RowCount := NewColCount;
if NewRowCount > Old then
begin
for C := 0 to ColCount-1 do
begin
for R := Old to NewRowCount-1 do
Objects[C, R] := TMyCell.Create;
end;
end;
end;
end;
but now whenever I drop my control on a form, the rowcount is 93... where do I set that rowCount? Because I DONT.
And still, if I increase the RowCount from 93 to something else like 100, then my Objects exist for the first 93 rows but they do not get created for the 93-100 rows...
So the idea sounded great, but it does not work as I expect it...
Any thoughts? Am I doing it wrong?