Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何防止在Delphi7中编辑tstringgrid中的非空单元格?_Delphi - Fatal编程技术网

如何防止在Delphi7中编辑tstringgrid中的非空单元格?

如何防止在Delphi7中编辑tstringgrid中的非空单元格?,delphi,Delphi,我有个问题,需要你的帮助 我打算做数独游戏。在我的Stringgrid中,我在[grid1.单元格[8,8]:=inttostr(2);grid1.单元格[2,5]:=inttostr(9);等]之前用数字填充了一些单元格,数字的文本字体颜色为黑色。现在我希望玩家不能更改(编辑)以前的值,只能添加到空单元格(只能更改自己的值)。 插入单元格的值必须是不同的文本字体颜色(exp:clRed) 这两个案子我需要帮助。 提前谢谢 没有公开的方法来中断单元格编辑过程,但您可以创建一个子类并重写其受保护的

我有个问题,需要你的帮助 我打算做数独游戏。在我的Stringgrid中,我在[grid1.单元格[8,8]:=inttostr(2);grid1.单元格[2,5]:=inttostr(9);等]之前用数字填充了一些单元格,数字的文本字体颜色为黑色。现在我希望玩家不能更改(编辑)以前的值,只能添加到空单元格(只能更改自己的值)。 插入单元格的值必须是不同的文本字体颜色(exp:clRed) 这两个案子我需要帮助。
提前谢谢

没有公开的方法来中断单元格编辑过程,但您可以创建一个子类并重写其受保护的方法。在该控件子类中,例如,您可以创建一个事件来控制是否创建inplace编辑器

以下插入器类引入了
OnCanEdit
事件,该事件将在创建inplace编辑器之前触发,并允许您通过其
CanEdit
参数决定是否要创建它:

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;
此示例显示了如何仅允许编辑行和列索引大于2的单元格,这不是您的情况,但我相信您知道该怎么做:

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;

虽然这个问题已经有四年多的历史了,但我之所以回答这个问题,是因为最初的答案并非绝对正确。事实上,有一种方法可以防止编辑特定单元格:

您可以设置TStringGrid OnSelectCell的CanSelect参数:

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;
过程TForm1.FormCreate(发送方:TObject);
开始
StringGrid1.Options:=StringGrid1.Options+[GoEdit];
StringGrid1.单元格[2,3]:='3';
StringGrid1.Objects[2,3]:=指针(1);
结束;
过程TForm1.StringGrid1SelectCell(发送方:toObject;ACol,ARow:Integer;
变量CanSelect:Boolean);
开始
如果StringGrid1.Objects[ACol,ARow]nil,则
CanSelect:=false;
结束;

阻止单元格的决定可以通过为相应的对象设置一个阻止值来完成

这是一个很好的例子,说明了为什么从UI中分离数据很重要。对于您的问题,我认为在子类控件中重写
CanEditShow
方法可能是一个好地方。感谢您的回答,但我得到了错误:[expect':'但是'='found]TCanEditEvent=过程(发送者……这部分很好。当然,如果我没有明确说明,我正在测试我发布的代码。这是我在Delphi 7中直接测试的。它在我的个人资料页面中,但很抱歉,今天是星期五,我没有动机完成你的项目。将此帖子中的代码复制粘贴到你的代码编辑器中有什么问题吗?此外,我故意只回答了关于编辑的问题的第一部分,因为该控件本身不支持该部分。另一部分是关于着色的问题,您可以在Internet上的数百个地方找到。谢谢大家。只是得到了错误[expect':'但是'='found]这很奇怪。我无法解释为什么会出现此错误。可以肯定的是,下面展示了如何将本文中的代码合并在一起(第一个视图中不清楚)。如果这也没有帮助,请给我发封邮件。