Android 如何在Delphi中使用构造函数来传输具有两种形式的对象?

Android 如何在Delphi中使用构造函数来传输具有两种形式的对象?,android,delphi,constructor,bluetooth,delphi-xe6,Android,Delphi,Constructor,Bluetooth,Delphi Xe6,嗨,我有一个Delphi构造函数问题。我想要一个具有我自己类参数的构造函数。我有两张表格。。在第一种形式中,我的类对象获取信息,然后我调用第二种形式。通过第二种形式,我调用构造函数并将我的类对象给他 这里是代码:TForm2 ... constructor TForm2.create(bluetoothconfiguration : TAndroidBluetooth); begin inherited create; bt := bluetoothconfiguratio

嗨,我有一个Delphi构造函数问题。我想要一个具有我自己类参数的构造函数。我有两张表格。。在第一种形式中,我的类对象获取信息,然后我调用第二种形式。通过第二种形式,我调用构造函数并将我的类对象给他

这里是代码:TForm2

...
constructor TForm2.create(bluetoothconfiguration : TAndroidBluetooth);
  begin
    inherited create;

    bt := bluetoothconfiguration; 

  end;
...
这里我调用构造函数:TForm1

...
procedure TForm1.lv_devicesItemClick(const Sender: TObject;
  const AItem: TListViewItem);
   var
   form : TForm2;
begin
      bt.CreateConnectionToBluetoothDevice(AItem); //Stellt eine Verbindung mit einem Gerät her

      form := TForm2.Create(bt); //bt is the class object with the information

      form.Show();

end;
...

我想从我的对象发送第二个表单:(

您正在调用的继承构造函数希望传递一个owner参数。您没有这样做

应向构造函数添加所有者参数,并将其传递给继承的构造函数:

constructor TForm2.Create(AOwner: TComponent; Config: TAndroidBluetooth);
begin
  inherited Create(AOwner);
  ....
end;
然后在创建表单时传递所有者:

form := TForm2.Create(Self, bt);
也许你想换一个主人,我从这里看不出来


最后一点建议。在询问有关编译错误的问题时,请始终在问题中包含编译错误文本,以便我们了解您的问题。

您正在调用的继承构造函数希望传递一个所有者参数。您没有这样做

应向构造函数添加所有者参数,并将其传递给继承的构造函数:

constructor TForm2.Create(AOwner: TComponent; Config: TAndroidBluetooth);
begin
  inherited Create(AOwner);
  ....
end;
然后在创建表单时传递所有者:

form := TForm2.Create(Self, bt);
也许你想换一个主人,我从这里看不出来


最后一点建议。当询问有关编译错误的问题时,请始终在问题中包含编译错误文本,以便我们知道您在问什么。

这里您指的是一种依赖项注入(DI):您有一个依赖外部对象进行正确操作的窗体。人们采取的明显方法是向窗体的构造函数添加参数。但David上面所说的是正确的:您不能简单地忽略“AOOwner”参数—VCL框架已经要求注入的另一个值

这是一个经典的问题,没有得到太多的讨论,所以我想我会花一分钟来详细阐述它

当您创建表单时,它很少单独存在——只有主表单在大多数情况下是这样工作的。表单通常用于执行以下三项操作之一:(1)收集并返回新数据;(2)接受数据进行编辑并返回编辑后的数据;(3)接受用于进行选择的某些数据,并以某种方式返回选择

当您使用数据感知控件时,表单可能看起来是自给自足的;实际上,VCL框架是(在幕后)注入的所有的数据感知控制机制。如果您没有在IDE中设置表和字段数据,那么您在创建表单时必须显式地注入所有这些数据,尽管大多数人都不是这样做的。(我的意思是,为什么还要使用数据感知控制呢?)

相反,如果您制作的表单不使用或不能使用数据感知控件(例如,因为它们从没有定义TDataset的其他类型的外部接口获取数据),则需要首先注入初始字段值,然后获取更新后的值

如果你使用的是几个值,这很好——通常有人会将它们放入构造函数中。但是如果你有一堆值(比如说,50),你会怎么做?你不能将它们全部放入构造函数中

更糟糕的是,您可能需要获取更新。如果您通过构造函数注入更新,则需要将其中一些设置为“var”参数。这是一种非常糟糕的设计实践,尽管很常见

所以下一步人们会想,“哦,我将把所有这些值放入一个对象中,然后通过构造函数传递对象!”

但很多时候,这些值已经存在于其他对象中,这意味着您的工作量增加了一倍,因为现在您需要将它们传递到代理对象中,并从代理对象中获取它们——具有讽刺意味的是,您创建了代理对象,以便简化将它们传递到表单中并从表单中获取它们

请注意,我们讨论的这种方法在DI术语中称为“构造函数注入”。显然,它有其局限性

另一种方法是所谓的“属性注入”或“setter注入”

“构造函数注入”的主要优点是,当对象的构造完成时,值都已设置好并准备就绪。使用“属性/设置器注入”可以构造对象,然后注入依赖值,然后显示表单。表单关闭后,可以从其属性(或getter)中提取更新的值,然后根据需要释放表单

在Delphi中,您可能需要重写这些表单的OnClose方法,将操作设置为caHide,以便在表单关闭时不会释放表单(这可能是默认值;我似乎永远记不起来了)

一般来说,构造函数注入的代码是这样的:

try
  myobj := TMyObject.Create();  // an object with initial values to feed the form
  myobj.intval := 10; 
  myobj.str := "hello world!"

  myform := TMyForm.Create( self, myobj );
  myform.ShowModal(); 
  // form could be freed here if OnClose's Action has been set to caFree
  // this means myform is no longer valid
  // however, it may be <> NIL even if it HAS been freed!
  // if not freed, then free it
  myform.Free();

  // now do something with the contents of myobj
  if (myobj.intval <> 10) then
    . . .
  if (myobj.str = '') then
    . . .
finally
  myobj.Free();
end;
试试看
myobj:=TMyObject.Create();//具有初始值的对象,用于向窗体提供数据
myobj.intval:=10;
myobj.str:=“你好,世界!”
myform:=TMyForm.Create(self,myobj);
myform.ShowModal();
//如果OnClose的Action设置为caFree,则可以在此处释放表单
//这意味着myform不再有效
//但是,即使它已被释放,也可能为零!
//如果没有释放,则释放它
myform.Free();
//现在对myobj的内容做些什么
如果(myobj.intval 10)那么
. . .
如果(myobj.str=''),则
. . .
最后
myobj.Free();
结束;
下面是属性注入的样子,假设表单中的每个字段(在本例中为intval和str)都有具有setter和getter(读/写方法)的单独属性:

try
  myform := TMyForm.Create( self );
  myForm.intval := 10;
  myform.str := "hello world!"
  myform.ShowModal(); // ensure the form is HIDDEN when it closes, not freed!

  // now do something with the field values -- myform must still be valid!
  if (myform.intval <> 10) then
    . . .
  if (myform.str = '') then
    . . .
finally
  myform.Free();
end;
试试看
myform:=TMyForm.Create(self);
myForm.intval:=10;
myform.str:=“你好,世界!”
myform.showmodel();//确保表单在关闭时隐藏,而不是释放!
//现在对字段值执行一些操作——myform必须仍然有效!
if(myform.intval)