我只想在TDBGrid中编辑一些单元格。在给定的列中,一些但不是所有单元格都是可编辑的,因此我不能只为整列设置Column.ReadOnly,然后保持这种方式。
最好使用哪些事件,以便在输入单元格时获得控制权。我可能会使用TDbGrid.ColumnEnter来捕获水平移动和TDataSet.AfterScroll以在网格中进行垂直移动。或者我也许可以使用TDBGrid.DrawColumnCell(我已经用它来改变某些单元格的颜色......)
而且我也无法找出改变单元格只读状态的最佳方法。我可以设置底层的TTable.Field.ReadOnly或TDbGrid.Columns [] .ReadOnly。
我可以尝试上述所有内容,但之后我依靠我的测试来确定网格是如何实现的,并且可能会忽略某些情况。如果有警告等,我更愿意知道VCL是否提供了管理这种需求的方法。
相关:ReadOnly TDBGrid/TwwDBGrid Cell in Delphi?,但不通过键盘处理滚动。
答案 0 :(得分:3)
您可以覆盖CanEditModify功能并添加您希望的条件。这可以通过添加新事件或仅通过interposerclass创建新组件来完成。
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.
答案 1 :(得分:1)
DBGrid决定是否根据大量输入显示文本编辑框:
如果要使DBGrid列中的某些单元格可编辑,并且同一列中的其他单元格不可编辑,则您必须自己执行此操作。 DBGrid通过网格范围和列式覆盖查找数据集的大多数提示。
我不记得数据集字段CanModify是否可以配置为根据各个行数据返回不同的true或false。如果是这样,这可能是您最好的选择。 DBGrid将尊重CanModify返回的任何字段。
如果CanModify不是每行上下文,您可以使用逻辑来决定哪些单元格可以在CanEditModify中编辑。创建一个继承自TDBGrid(或TCustomDBGrid)的新网格类,并覆盖CanEditModify虚拟方法。您应该首先执行自定义逻辑,然后在逻辑不适用时调用继承的方法。您可能需要覆盖一些其他方法来微调外观,例如CanEditShow。