将表单的第二个实例绑定到数据模块的第二个实例?

时间:2013-10-16 19:03:35

标签: delphi data-binding delphi-2010

我有一个Form,它具有绑定到数据模块中数据集的数据感知控件。我需要在同一个应用程序中创建表单和数据模块的其他实例。

我删除了首次将数据模块添加到项目时自动创建的全局变量。令我高兴的是,设计器中的控件仍然可以绑定到数据模块中没有此全局变量的数据集。我假设IDE正在解析数据模块的dfm,因此设计人员仍然可以“看到”数据模块。 (如果没有在IDE中加载数据模块,则数据源列表为空)

当我在运行时创建表单的两个实例和两个datamodule实例时,表单的两个实例似乎只绑定到创建的第一个数据模块。检查数据模块的第二个实例会发现Name属性具有在设计时不存在的数字后缀。

表单取决于数据模块中的大量数据集。是否有更简单的方法将第二个表单实例绑定到第二个数据模块的数据集,而不需要为每个控件使用手动编码SomeControl.DataSource := Module2.dsSomeData

我也愿意接受其他建议。一种解决方案是将数据集移动到表单本身。如果设计时数据绑定仅适用于单身人士,那似乎仍然是一种耻辱。

3 个答案:

答案 0 :(得分:1)

看看这个问题:
separate dataset instances using datamodules in delphi

基本上答案是创建DataModule,然后创建Form,然后将创建的DataModule的名称设置为空字符串。这将使初始数据绑定发生,但阻止其他形式看到该模块。

此外,创建的下一个版本仍将具有原始名称(不需要数字后缀)。

答案 1 :(得分:1)

  

我有一个Form,它具有绑定到DataModule中DataSet的数据感知控件。

这是不可能的。间接地,ok同意,但两者之间必须有一个必要的DataSource。 (从你的问题的其余部分我们必须提炼出那些DataSource在DataModule上的信息,但问题当然可以更加透明。)

  

我删除了首次将DataModule添加到项目时自动创建的全局变量。

好,坚持那个习俗!

  

令我高兴的是,设计器中的控件仍然可以绑定到DataModule中没有此全局变量的DataSet。我假设IDE正在解析DataModule的dfm,因此设计人员仍然可以“看到”DataModule。

DataSource和DataSet之间存在相同的不正确/混淆,但您部分正确:要使IDE能够找到DataModule,必须满足以下条件:

  • 必须在IDE会话期间至少创建/打开一次DataModule(之后可能会在会话期间关闭),请参阅(*),
  • 该DataModule的单位必须出现在表单位的使用列表中。
  

当我在运行时创建两个Form实例和两个DataModule实例时,Form的两个实例似乎只绑定到第一个创建的DataModule。

这是因为您依赖于在运行时不起作用的自动设计时绑定。该绑定取决于DataModule的名称。但这不是依赖于设计时绑定的唯一缺点,请参阅(*)。

  

检查DataModule的第二个实例会发现Name属性具有在设计时不存在的数字后缀。

在序列号后缀前加上下划线。它似乎是设计的。不能有多个具有相同名称的DataModule(或Forms),这与不能与兄弟或子组件具有相同名称的组件相当。但有点奇怪,因为在没有提供所有者或甚至不同的所有者时,相同的规则仍适用于DataModules和Forms,这与默认的TComponent行为不同。我在RTL / VCL代码中找不到证据或解释。也许它与屏幕变量中保存的所有DataModule和Forms有关。我们必须接受,但这不是问题。

  

表单依赖于DataModule中的大量DataSet。是否有更简单的方法将第二个Form实例绑定到第二个DataModule的DataSet,而不需要为每个控件使用手动编码SomeControl.DataSource := Module2.dsSomeData? ...一种解决方案是将DataSet移动到Form本身。

其中dsSomedata是DataSource!

是的,有一种更简单的方法。而不是将DataSet放在窗体上,而是将DataSource放在窗体上。通常,与数据控件的数量相比,Form通常只有一个或几个DataSource。这样数据控件 - DataSource绑定保持不变(因为两者都是从同一个DFM读取),并且只有DataSource的DataSet设置仍然需要手动设置:

  TCustomerForm = class(TForm)
    DataSource: TDataSource;
    procedure FormCreate(Sender: TObject);
  private
    FData: TCustomerDataModule;
  end;

procedure TCustomerForm.FormCreate(Sender: TObject);
begin
  FData := TCustomerDataModule.Create(Self);
  DataSource.DataSet := FData.Query;
end;

或者,当您想要从DataModule创建表单时:

  TCustomerForm = class(TForm)
    DataSource: TDataSource;
  private
    FData: TCustomerDataModule;
    procedure SetData(Value: TCustomerDataModule);
  public
    property Data: TCustomerDataModule read FData write SetData;
  end;

procedure TCustomerForm.SetData(Value: TCustomerDataModule);
begin
  if FData <> Value then
  begin
    FData := Value;
    DataSource.DataSet := FData.Query;
  end;
end;

(*)在具有许多Forms和DataModule的大型项目中,很常见的是不打开IDE中的每个DataModule,并且(DataSource。)DataSet设置很容易丢失。依赖于DataModule名称的设计时绑定,可能会导致您的表单永远不会显示任何数据。这是一个很难预见的错误,无需检查每个Form的(DataSource。)DataSet设置。

以上述方式完成所有操作可确保在运行时正确创建DataModule,并确保提供DataSet,Fields等的IDE的所有设计时功能和智能......

答案 2 :(得分:0)

我有同样的问题。我使用了以下解决方案。

我的2个表单实例共享相同的DataModule实例。这两种形式不会同时出现。我的优点是,2个表单始终显示相同的数据,因为我的数据在内存中缓存,TCLientDataSet

e.g。

_dmSachkonto := TCachedDataModules.Instance.Add(TdmSachkonto) as TdmSachkonto;

TdmSachkonto是我的DataModule。