Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

TStringGrid column locked

Status
Not open for further replies.

rcloutie

Programmer
May 26, 2005
164
CA
Hi all,

I'm trying to implement in my VCL (descendant of TStringGrid) a column read only feature (locked).

Setting SelectCell Result=False works but what I want to do is to set focus to the column but cancel any attempt to change data (either by click or keypress).

Thanks a lot in advance

 
Also, how to hide a column (setting ColWidth=0 works but still have the column's separator line and when multiple columns are hidden, the result is a wide column's separator line...)
 
This isn't quite the same thing, but what I needed to do was set the focus to the only cell that was input capable on the row when any cell on that row was clicked. Perhaps it will give you an idea or two. I didn't see any reason to leave the user in a non-editable cell. Wouldn't that be frustrating?
Code:
const
  COL_TITLE       = 1;   // visible - constant
  COL_SEQ         = 2;   // visible - user can change

{Select a specific cell for a specified row of a string grid.}
procedure SelectColumnX( Grid:TObject; ACol,ARow:integer );
var
  xRect: TGridRect;
begin
  xRect.Left   := ACol;
  xRect.Top    := ARow;
  xRect.Right  := ACol;
  xRect.Bottom := ARow;
  (Grid As TStringGrid).Selection := xRect;
end;

{Force selection to column 2 (SEQ) for any SelectCell operation.}
procedure TQSpecs.StringGrid1SelectCell(Sender:TObject; ACol,
  ARow: Integer; var CanSelect: Boolean);
begin
  CanSelect := (ACol = COL_SEQ);
  SelectColumnX( Sender, COL_SEQ, ARow );
end;
As for hiding columns, try setting .ColWidths to -1 instead of zero.

 
Not really frustrating: the locked column displays a bitmap Check On/Off (managed into MouseUp)...

The problem is when option goEditing is set, the InplaceEditor is shown after 2 clicks :(

Do you know how to flush the InplaceEditor?

Hiding columns works well with setting ColWidth to -1,
but horz scrollbar always appears ??? Anyway thanks a lot!
 

Funny thing. That's exactly what I'm working with. A check box in column one (using bitmaps of checked and unchecked boxes), editable text in column 2 and the other columns non-editable.

Here is more of my code.
Code:
const
  COL_YESNO       = 0;   // visible - checkbox - user can click to toggle
  COL_TITLE       = 1;   // visible - constant
  COL_SEQ         = 2;   // visible - user can change
  COL_DESCRIPTION = 3;   // visible - constant
  COL_TABLECODE   = 4;   // remaing columns hidden...
  COL_COLUMN      = 5;
  COL_ACCUM       = 6;
  COL_LENGTH      = 7;  // not actually used.
  COL_TYPE        = 8;  // not actually used.
  COL_SAVESELECT  = 9;
  COL_SAVESEQ     = 10;
  COL_FIRSTHIDDEN = COL_TABLECODE;
  COL_LASTHIDDEN  = COL_SAVESEQ;

{Toggle text in the indicated column of a string grid.}
procedure ToggleColumnText( Grid:TObject; ACol,ARow:integer;
                            Text1:string; Text2:string='' );
begin
  with Grid as TStringGrid do
  if ARow >= FixedRows then begin
    if Cells[ACol, ARow] = Text1 then Cells[ACol,ARow] := Text2
                                 else Cells[ACol,ARow] := Text1;
  end; {if ARow}
end;

{Toggle L.H. column (check box) on any click in column zero.}
procedure TQSpecs.StringGrid1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  nCol,nRow:integer;
begin
  (Sender as TStringGrid).MouseToCell(X,Y,nCol,nRow);
  if nCol=COL_YESNO then ToggleColumnText( Sender, nCol, nRow, 'Yes' );
end;

{Toggle checkbox on space, allow [Esc] to un-do keying, else only 0-9 + Bs.}
procedure TQSpecs.StringGrid1KeyPress(Sender: TObject; var Key: Char);
var
  nRow:integer;
begin
  with Sender as TStringGrid do begin
    nRow := Selection.Top;
    if (Key = ' ') then
      begin
        ToggleColumnText( Sender, 0, nRow, 'Yes' );
        Key := Chr(0);
        EditorMode := False;
      end {if space}
    else
      begin
        if not (Key in ['0'..'9',#8,#13,#26,#27]) then Key := #0;      
        if Ord(Key) = 27 then Key := Chr(26);
      end;
  end; {with}
end;

{If user presses <Enter> while in grid, process as if pbOk clicked.}
procedure TQSpecs.StringGrid1KeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
   if Key = 13 then begin
    StringGrid1.EditorMode := False;
    pbOkClick( Sender );
  end;
end;

{Override grid draw cell to use check box in col zero and center SEQ no.}
procedure TQSpecs.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  ARect: TRect; State: TGridDrawState);
  {1 - Draw a check box in the specified rectangle.}
  {1} procedure DrawCheckBox( ACanvas:TCanvas; ARect:TRect; YesOrNo:string );
  {1} var
  {1}   bBitMap:TBitMap;
  {1}   PutHere:TRect;
  {1} begin
  {1}   {Paint a checkbox 4 pixels over and 1 pixel down.}
  {1}   PutHere := Rect(ARect.Left+4,ARect.Top+1,ARect.Left+17,ARect.Top+14);
  {1}   if YesOrNo = 'Yes' then bBitMap := bmChecked else bBitMap := bmUnchecked;
  {1}   ACanvas.FillRect(ARect);
  {1}   ACanvas.CopyRect( PutHere, bBitMap.Canvas, Rect(0,0,12,12) );
  {1} end;
begin
  with Sender as TStringGrid do begin
    if (ACol=COL_YESNO) and (ARow >= FixedRows) then
          DrawCheckBox( Canvas, ARect, Cells[COL_YESNO,ARow] ); // First col.
    if (ARow=000) then
          CenterText(Canvas,ARect,Cells[ACol,0]);      // All cols in heading.
    if (ACol = COL_SEQ) then
          CenterText(Canvas,ARect,Cells[ACol,ARow]);   // All rows for Seq no.
  end; {with}
end;

{On Form Create: Initialize grid and other variables}
procedure TQSpecs.FormCreate(Sender: TObject);
begin
  :
  :
  bmChecked      := TBitMap.Create;
  bmUnchecked    := TBitMap.Create;
  ImageList1.GetBitmap(0,bmUnchecked);
  ImageList1.GetBitmap(1,bmChecked);
  :
  :
end;
"CenterText" is one of my standard library routines for working with TStringGrid. Just delete those lines if you don't have it available.

 
I solved my problem including some code within SelectCell:

if bColLock then
Options := Options - [goEditing]
else
Options := Options + [goEditing];
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top