2

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

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

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

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

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

4

3 回答 3

1

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

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

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

于 2013-10-16T20:07:18.703 回答
1

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

这是不可能的。间接地,好的同意,但两者之间必须有一个必要的数据源。(从您的其余问题中,我们必须提炼出这些数据源在 DataModule 上的信息,但这个问题肯定会更加透明。)

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

好,坚持这个习惯!

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

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

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

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

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

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

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

Form 依赖于 DataModule 中的很多 DataSet。有没有一种更简单的方法可以将第二个 Form 实例绑定到第二个 DataModule 的 DataSet,而无需SomeControl.DataSource := Module2.dsSomeData为每个控件手动编码?...一种解决方案是将数据集移动到表单本身。

其中dsSomedata是数据源!

是的,有一个更简单的方法。不是将 DataSets 放在 Form 上,而是将 DataSources 放在 Form 上。通常,与数据控件的数量相比,Form 通常只有一个或几个 DataSource。这样数据控件 - DataSource 绑定保持不变(因为两者都是从同一个 DFM 读取的),并且只有 DataSources 的 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 名称的设计时绑定可能会导致您的表单永远不会显示任何数据。如果不检查每个表单的 (DataSource.)DataSet 设置,这是一个很难预见的错误。

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

于 2013-10-17T20:08:00.600 回答
0

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

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

例如

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

TdmSachkonto 是我的数据模块。

于 2013-10-17T10:00:09.170 回答