Delphi 从其他表单访问DBGrid1.Columns[1].Title.Caption
我正在尝试从另一个表单访问dbgrid.field的Delphi 从其他表单访问DBGrid1.Columns[1].Title.Caption,delphi,mdichild,dbgrid,mdiparent,tform,Delphi,Mdichild,Dbgrid,Mdiparent,Tform,我正在尝试从另一个表单访问dbgrid.field的标题 我在这里使用MDI,两个表单都是MDI子级 我试图从另一个窗体执行以下ShowMessage,但它导致访问冲突: ShowMessage(Form1.DBGrid1.Columns[1].Title.Caption); // 1st try ShowMessage(Unit1.Form1.DBGrid1.Columns[1].Title.Caption); // 2nd try 已在两个窗体之间使用集合 错误消息是 模块中地址0000
标题
我在这里使用MDI,两个表单都是MDI子级
我试图从另一个窗体执行以下ShowMessage
,但它导致访问冲突:
ShowMessage(Form1.DBGrid1.Columns[1].Title.Caption); // 1st try
ShowMessage(Unit1.Form1.DBGrid1.Columns[1].Title.Caption); // 2nd try
已在两个窗体之间使用集合
错误消息是
模块中地址000010363F9处的访问冲突。读取地址00000000 6F0
我错过了什么
更新:这是这个案例的精确复制(RME) MDI父级
unit MainUnit;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Menus;
type
TParentForm = class(TForm)
mmMenu: TMainMenu;
miForm1: TMenuItem;
miForm2: TMenuItem;
procedure miForm1Click(Sender: TObject);
procedure miForm2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
ParentForm: TParentForm;
implementation
uses
Form1Unit, Form2Unit;
{$R *.dfm}
procedure TParentForm.miForm1Click(Sender: TObject);
begin
TChildForm1.Create(self).Show;
end;
procedure TParentForm.miForm2Click(Sender: TObject);
begin
TChildForm2.Create(self).Show;
end;
end.
MDI子窗体1
unit Form1Unit;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Data.DB, Datasnap.DBClient,
Datasnap.Provider, MemDS, DBAccess, Uni, UniProvider, MySQLUniProvider,
Vcl.Grids, Vcl.DBGrids;
type
TChildForm1 = class(TForm)
dbgrd1: TDBGrid;
ucn1: TUniConnection;
mup1: TMySQLUniProvider;
uq1: TUniQuery;
dsp1: TDataSetProvider;
cds1: TClientDataSet;
ds1: TDataSource;
smlntfldcds1actor_id: TSmallintField;
strngfldcds1first_name: TStringField;
strngfldcds1last_name: TStringField;
dtmfldcds1last_update: TDateTimeField;
private
{ Private declarations }
public
{ Public declarations }
end;
var
ChildForm1: TChildForm1;
implementation
uses
MainUnit, Form2Unit;
{$R *.dfm}
end.
MDI子窗体2
unit Form2Unit;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TChildForm2 = class(TForm)
btn1: TButton;
procedure btn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
ChildForm2: TChildForm2;
implementation
uses
MainUnit, Form1Unit;
{$R *.dfm}
procedure TChildForm2.btn1Click(Sender: TObject);
begin
ShowMessage(Form1Unit.ChildForm1.dbgrd1.Columns[2].Title.Caption);
end;
end.
错误消息
模块“Project7.exe”中地址0081B314处的访问冲突。读到
地址:000003D0
可能有一个对象没有分配,我怀疑它可能是
列[1]
(注意列集合是基于零的索引,因此第一列是列[0]
)
试试这个:
if(not Assigned(Form1)) then
raise Exception.Create('Form1 not assigned');
if(not Assigned(Form1.DBGrid1)) then
raise Exception.Create('Form1.DBGrid1 not assigned');
if(Form1.DBGrid1.Columns.Count < 2) then
raise Exception.Create('Form1.DBGrid1 has not the Columns[1] item');
如果(未分配(表格1)),则
引发异常。创建('Form1 not assigned');
如果(未赋值(Form1.DBGrid1)),则
引发异常。创建('Form1.DBGrid1 not assigned');
如果(Form1.DBGrid1.Columns.Count<2),则
Create('Form1.DBGrid1没有列[1]项');
编写类似于Form1Unit.ChildForm1.dbgrd1.Columns[2].Title.Caption)的代码是在制造等待发生的事故,
因为它假定要操作的ChildForm1实例是自动创建的ChildForm1
使用自动创建的表单(除了主表单之外)通常被认为是不好的做法,因为它会导致类似这样的事故,所以最好摆脱使用表单的习惯
从另一个窗体(或数据模块)访问一个窗体(或数据模块)时,一种不太容易发生事故的技术是在“其他”窗体上编写代码,这种方式要求您指定要操作的对象实例。大概是这样的:
procedure TChildForm2.DoSomethingWithForm1(Form1Instance : TForm1);
begin
ShowMessage(Form1Instance.dbgrd1.Columns[2].Title.Caption);
end;
procedure TChildForm2.btn1Click(Sender: TObject);
begin
DoSomethingWithForm1(Form1Unit.ChildForm1);
end;
这样做的意义在于,它迫使你思考你选择的是哪一个Form1实例
意思是,因为当你有多个相同的实例时,得到正确的答案是非常重要的
表单(即使您没有,因为它可能会提示您是否已创建实例)。实际上,列已经存在于引用它的表单中。我指的是本案中的具体专栏。我不确定你给的代码是否有效。我尝试使用ShowMessage以相同的形式访问它,但它确实是使用-ShowMessage(DBGrid1.Columns[1].Title.Caption)执行的;所以我认为Form1
对象没有赋值,或者它不属于预期的类类型。试着检查一下我忘了提到我在这里使用MDI。顺便说一下,这两个窗体都是MDI子窗体。是否确实Form1指向窗体的实例?。你能告诉我们你在哪里创建表单的代码吗?请在遇到错误时,将错误消息复制到你的问题上(右键单击消息窗口,然后按Ctrl-C)。请不要在评论中详述你的问题。您的问题。请显示您正在使用的代码,并在上下文中显示它,就像ShowMessage(…)这样的单个语句-读者不必猜测。您必须指定ChildForm1:=TChildForm1.Create(Self);ChildForm1.Show()代码>。在你的代码中,ChildForm1
是零。所以,Juke。如果你按照@Fabrizio的建议检查Form1(等)的分配,你就会得到答案!或者至少有一个明确的迹象表明什么可能是错的,我知道。我刚从这里学到的。我已经更改了一些与此相关的代码。非常感谢你。