Delphi 将TDbGrid中的某些单元格设置为可编辑

Delphi 将TDbGrid中的某些单元格设置为可编辑,delphi,tdbgrid,Delphi,Tdbgrid,我只想要一些在TDBGrid中可编辑的单元格。在一个给定的列中,一些但不是所有的单元格都是可编辑的,所以我不能只为整个列设置column.ReadOnly,然后保持这种状态 什么样的事件最适合使用,以便我可以在输入单元格时获得控制权。我可以使用TDbGrid.ColumnEnter捕捉水平移动,使用TDataSet.AfterScroll捕捉网格中的垂直移动。或者我可以使用TDBGrid.DrawColumnCell(我已经在使用它来更改某些单元格的颜色…) 我也很难找到改变单元格只读状态的最佳

我只想要一些在TDBGrid中可编辑的单元格。在一个给定的列中,一些但不是所有的单元格都是可编辑的,所以我不能只为整个列设置column.ReadOnly,然后保持这种状态

什么样的事件最适合使用,以便我可以在输入单元格时获得控制权。我可以使用TDbGrid.ColumnEnter捕捉水平移动,使用TDataSet.AfterScroll捕捉网格中的垂直移动。或者我可以使用TDBGrid.DrawColumnCell(我已经在使用它来更改某些单元格的颜色…)

我也很难找到改变单元格只读状态的最佳方法。我可以设置底层TTable.Field.ReadOnly或TDbGrid.Columns[].ReadOnly

我可以对以上所有内容进行实验,但我会依靠测试来确定网格是如何实现的,并且可能会忽略某些情况。我想知道VCL是否提供了一种管理这种需求的方法,是否有警告,等等


相关:,但不处理通过键盘的滚动。

您可以覆盖CanEditModify功能并添加所需条件。这可以通过添加一个新事件创建一个新组件来完成,也可以通过一个InteroperClass来完成

unit Unit6;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, ADODB, Grids, DBGrids;

type
  TDBGrid=Class(DBGrids.TDBgrid)
    function CanEditModify: Boolean; override;
    Property Col; // make property col visible
  End;

  TForm6 = class(TForm)
    DBGrid1: TDBGrid;
    ADOConnection1: TADOConnection;
    ADODataSet1: TADODataSet;
    DataSource1: TDataSource;
    ADODataSet1Componame: TStringField;
    ADODataSet1TrackTitle: TStringField;
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form6: TForm6;

implementation

{$R *.dfm}

{ TDBGrid }

function TDBGrid.CanEditModify: Boolean;
var
 f:TField;
 c:Integer;
begin
  Result := inherited CanEditModify;
  c := Col;
  if dgIndicator in Options then dec(c); 
  F := Columns[c].Field;
  if Assigned(F) then
    begin // here just an example condition
      if (f.FieldName='TrackTitle') then
        if Pos('aa',F.AsString)>0 then Result := False;
      // you also can access the dataset via
      // if f.DataSet.FieldByName('xy').SomeCondition then ....    
    end;
end;

end.

您可以重写CanEditModify函数并添加所需的条件。这可以通过添加一个新事件创建一个新组件来完成,也可以通过一个InteroperClass来完成

unit Unit6;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, ADODB, Grids, DBGrids;

type
  TDBGrid=Class(DBGrids.TDBgrid)
    function CanEditModify: Boolean; override;
    Property Col; // make property col visible
  End;

  TForm6 = class(TForm)
    DBGrid1: TDBGrid;
    ADOConnection1: TADOConnection;
    ADODataSet1: TADODataSet;
    DataSource1: TDataSource;
    ADODataSet1Componame: TStringField;
    ADODataSet1TrackTitle: TStringField;
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form6: TForm6;

implementation

{$R *.dfm}

{ TDBGrid }

function TDBGrid.CanEditModify: Boolean;
var
 f:TField;
 c:Integer;
begin
  Result := inherited CanEditModify;
  c := Col;
  if dgIndicator in Options then dec(c); 
  F := Columns[c].Field;
  if Assigned(F) then
    begin // here just an example condition
      if (f.FieldName='TrackTitle') then
        if Pos('aa',F.AsString)>0 then Result := False;
      // you also can access the dataset via
      // if f.DataSet.FieldByName('xy').SomeCondition then ....    
    end;
end;

end.

DBGrid根据大量输入决定是否显示文本编辑框:

  • DBGrid本身是否为只读
  • 数据集是否为只读
  • 列是否为只读
  • 字段是否为只读
  • 是否可以将数据集置于编辑模式
  • 如果要使DBGrid列中的某些单元格可编辑,而使同一列中的其他单元格不可编辑,则必须自己执行此操作。DBGrid在数据集中查找其大部分线索,并使用网格范围和列覆盖

    我不记得dataset字段CanModify是否可以配置为基于单个行数据返回不同的true或false。如果是这样,这可能是你最好的选择。DBGrid将接受CanModify返回的任何字段


    如果CanModify不是每行上下文,您可以将逻辑放在CanEditModify中决定哪些单元格应可编辑。创建从TDBGrid(或TCustomDBGrid)继承的新网格类,并重写CanEditModify虚拟方法。您可能应该首先执行自定义逻辑,然后在逻辑不适用时调用继承的方法。您可能需要覆盖一些其他方法来微调外观,例如CanEditShow。

    DBGrid根据大量输入决定是否显示文本编辑框:

  • DBGrid本身是否为只读
  • 数据集是否为只读
  • 列是否为只读
  • 字段是否为只读
  • 是否可以将数据集置于编辑模式
  • 如果要使DBGrid列中的某些单元格可编辑,而使同一列中的其他单元格不可编辑,则必须自己执行此操作。DBGrid在数据集中查找其大部分线索,并使用网格范围和列覆盖

    我不记得dataset字段CanModify是否可以配置为基于单个行数据返回不同的true或false。如果是这样,这可能是你最好的选择。DBGrid将接受CanModify返回的任何字段


    如果CanModify不是每行上下文,您可以将逻辑放在CanEditModify中决定哪些单元格应可编辑。创建从TDBGrid(或TCustomDBGrid)继承的新网格类,并重写CanEditModify虚拟方法。您可能应该首先执行自定义逻辑,然后在逻辑不适用时调用继承的方法。您可能需要覆盖一些其他方法来微调外观,例如CanEditShow。

    谢谢,bummi。这给了我一个起点。然而,当在D7中编译从您的示例中采用的一些代码时,在继承的行中出现了“不兼容类型”错误。另外,如果我希望有时将覆盖恢复到基类,那么语法结果是:=inherited??谢谢@罗伯特弗兰克,我现在没有D7。我做了一个编辑。。。您应该始终调用inherited以避免意外行为,修改或不修改继承的结果取决于您的代码。表1.FieldByName('MyFieldName')。只读:=;当我写我的第一篇博文时,我没有意识到我的状态是特定于记录的,不依赖于水平运动。我把这个作为一个评论,因为我会给bummi分数来回答,因为这个答案是最有帮助的,会让我回答我原来的问题谢谢,bummi。这给了我一个起点。然而,当在D7中编译从您的示例中采用的一些代码时,在继承的行中出现了“不兼容类型”错误。另外,如果我希望有时将覆盖恢复到基类,那么语法结果是:=inherited??谢谢@罗伯特弗兰克,我现在没有D7。我做了一个编辑。。。您应该始终调用inherited以避免意外行为,修改或不修改继承的结果取决于您的代码。表1.FieldByName('MyFieldName')。只读:=;当我写我的第一篇博文时,我没有意识到我的状态是特定于记录的,不依赖于水平运动。我把这作为一个评论,因为我会给回答的bummi点,因为是答案是最有帮助的,会引导我回答我原来的问题