Subject | RE: [IBO] Display partial rows in TIB_GRID |
---|---|
Author | Calin Pirtea |
Post date | 2005-05-16T03:20:52Z |
I've managed to do this cleanly without touching TCustomGrid.
For those interested, the changes are minimal:
procedure TIB_CustomGrid.SysDataChange( IB_Field: TIB_Column );
var
tmpInd: integer;
begin
if DataLink.Disabled then Exit;
if DataLink.Prepared then
begin
with Datalink.BDataset do
begin
{Change starts here}
VisibleGridRows;
if (GridRow[RowNum] >= FDataRowCount) and
(FPartialRowHeight > 0) and
not ((RowNum = (DataLink.BDataset.EofRowNum-1)) and
DataLink.BDataset.BufferHasEof) then
begin
Slide(GridRow[RowNum] - FDataRowCount + 1);
end;
{Change ends here}
UpdateRowCount;
if not UpdateRowPos( true ) then
begin
if not Assigned( IB_Field ) then
InvalidateRow( GridRow[ RowNum ], true )
else
if Assigned( FGridFields ) then
begin
tmpInd := FGridFields.IndexOf( IB_Field );
if tmpInd >= 0 then
InvalidateCell( GridCol[ tmpInd ], GridRow[ RowNum ] );
end;
end;
end;
InvalidateEditor;
if Assigned( InPlaceEditor ) then
InPlaceEditor.Modified := false;
UpdateScrollBar;
end;
end;
function TIB_CustomGrid.VisibleGridRows: longint;
var
ii: integer;
AGridHeight: longint;
tmpHeight: longint;
begin
Result := 0;
AGridHeight := 0;
for ii := 0 to FixedRows - 1 do
Inc( AGridHeight, RowHeights[ ii ] );
if RowLines or FixedRowLines then
Inc( AGridHeight, GridLineWidth * ( FixedRows + 1 ));
if HandleAllocated then
tmpHeight := ClientHeight
else
tmpHeight := Height;
while AGridHeight < tmpHeight do
begin
Inc( Result );
Inc( AGridHeight, DefaultRowHeight );
if RowLines or FixedRowLines then
Inc( AGridHeight, GridLineWidth );
end;
FDataRowCount := Result;
FPartialRowHeight := AGridHeight - tmpHeight;
{Change starts here}
if (FPartialRowHeight > 0) and (Result > 1) and
(DataLink <> nil) and
(DataLink.BDataset.BufferHasEof) and
(DataLink.BDataset.RowNum = (DataLink.BDataset.EofRowNum-1))
then
Dec(Result);
{Change ends here}
end;
The trick is to never allow the grid to stay on the partially visible row because ClampInView will kick in and ruin everything.
When you are on the last row the number of visible rows is reduced if the last one is partially visible. This way ClampInView will never change the grid row.
Cheers,
Calin Pirtea
COMMUNICARE DEVELOPMENT TEAM
Communicare Systems Pty Ltd
08 9332 2433
041 9906 150
08 9310 1516 (fax)
For those interested, the changes are minimal:
procedure TIB_CustomGrid.SysDataChange( IB_Field: TIB_Column );
var
tmpInd: integer;
begin
if DataLink.Disabled then Exit;
if DataLink.Prepared then
begin
with Datalink.BDataset do
begin
{Change starts here}
VisibleGridRows;
if (GridRow[RowNum] >= FDataRowCount) and
(FPartialRowHeight > 0) and
not ((RowNum = (DataLink.BDataset.EofRowNum-1)) and
DataLink.BDataset.BufferHasEof) then
begin
Slide(GridRow[RowNum] - FDataRowCount + 1);
end;
{Change ends here}
UpdateRowCount;
if not UpdateRowPos( true ) then
begin
if not Assigned( IB_Field ) then
InvalidateRow( GridRow[ RowNum ], true )
else
if Assigned( FGridFields ) then
begin
tmpInd := FGridFields.IndexOf( IB_Field );
if tmpInd >= 0 then
InvalidateCell( GridCol[ tmpInd ], GridRow[ RowNum ] );
end;
end;
end;
InvalidateEditor;
if Assigned( InPlaceEditor ) then
InPlaceEditor.Modified := false;
UpdateScrollBar;
end;
end;
function TIB_CustomGrid.VisibleGridRows: longint;
var
ii: integer;
AGridHeight: longint;
tmpHeight: longint;
begin
Result := 0;
AGridHeight := 0;
for ii := 0 to FixedRows - 1 do
Inc( AGridHeight, RowHeights[ ii ] );
if RowLines or FixedRowLines then
Inc( AGridHeight, GridLineWidth * ( FixedRows + 1 ));
if HandleAllocated then
tmpHeight := ClientHeight
else
tmpHeight := Height;
while AGridHeight < tmpHeight do
begin
Inc( Result );
Inc( AGridHeight, DefaultRowHeight );
if RowLines or FixedRowLines then
Inc( AGridHeight, GridLineWidth );
end;
FDataRowCount := Result;
FPartialRowHeight := AGridHeight - tmpHeight;
{Change starts here}
if (FPartialRowHeight > 0) and (Result > 1) and
(DataLink <> nil) and
(DataLink.BDataset.BufferHasEof) and
(DataLink.BDataset.RowNum = (DataLink.BDataset.EofRowNum-1))
then
Dec(Result);
{Change ends here}
end;
The trick is to never allow the grid to stay on the partially visible row because ClampInView will kick in and ruin everything.
When you are on the last row the number of visible rows is reduced if the last one is partially visible. This way ClampInView will never change the grid row.
Cheers,
Calin Pirtea
COMMUNICARE DEVELOPMENT TEAM
Communicare Systems Pty Ltd
08 9332 2433
041 9906 150
08 9310 1516 (fax)