简体   繁体   中英

How to prevent editing unempty cells in tstringgrid in delphi 7?

在此输入图像描述 I have a problem and need your help I am going to work on sudoku game. In my Stringgrid I've filled some cells with digits before [grid1.cells[8,8]:=inttostr(2); grid1.cells[2,5]:=inttostr(9); etc] and digits' text font color are black. Now I want player cannot change(edit) previous values and only able to add to empty cells(can change only its own values). And values inserted into cells have to be diffent text font color(exp: clRed) I need help in this two cases. Thanks in advance .

There is no public way to interrupt process of cell editing, but you can make a TStringGrid subclass and override its CanEditShow protected method. In this control subclass, you can eg make an event to control whether the inplace editor will be created or not.

The following interposer class introduces the OnCanEdit event which will fire before the inplace editor is created and allows to you decide whether you want to create it or not by its CanEdit parameter:

type
  TCanEditEvent = procedure(Sender: TObject; Col, Row: Longint;
    var CanEdit: Boolean) of object;

  TStringGrid = class(Grids.TStringGrid)
  private
    FOnCanEdit: TCanEditEvent;
  protected
    function CanEditShow: Boolean; override;
  public
    property OnCanEdit: TCanEditEvent read FOnCanEdit write FOnCanEdit;
  end;

implementation

{ TStringGrid }

function TStringGrid.CanEditShow: Boolean;
begin
  Result := inherited CanEditShow;

  if Result and Assigned(FOnCanEdit) then
    FOnCanEdit(Self, Col, Row, Result);
end;

This example shows how to allow editing only for cells with row and column index greater than 2, which is not your case, but I'm sure you understand what to do:

type
  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    procedure FormCreate(Sender: TObject);
  private
    procedure StringGridCanEdit(Sender: TObject; Col, Row: Longint; 
      var CanEdit: Boolean);
  end;

implementation

procedure TForm1.FormCreate(Sender: TObject);
begin
  StringGrid1.OnCanEdit := StringGridCanEdit;
end;

procedure TForm1.StringGridCanEdit(Sender: TObject; Col, Row: Integer;
  var CanEdit: Boolean);
begin
  // to the CanEdit parameter assign True if you want to allow the cell
  // to be edited, False if you don't
  CanEdit := (Col > 2) and (Row > 2);
end;

Although the question is over 4 years old I am answering because the initial Answer is not absolutely correct. In fact there is a way to prevent editing specific cells:

You can set the CanSelect parameter of the TStringGrid OnSelectCell:

procedure TForm1.FormCreate(Sender: TObject);
begin
  StringGrid1.Options := StringGrid1.Options+[goEditing];

  StringGrid1.Cells[2,3] := '3';
  StringGrid1.Objects[2,3] := Pointer(1);
end;

procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
  var CanSelect: Boolean);
begin
  if StringGrid1.Objects[ACol,ARow]<>nil then
    CanSelect := false;
end;

The decision to block a cell can be done by setting a blocking value to the corresponding Objects

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM