【问题标题】:Binding a second instance of a form to a second instance of a data module?将表单的第二个实例绑定到数据模块的第二个实例?
【发布时间】:2013-10-16 19:03:35
【问题描述】:

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

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

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

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

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

【问题讨论】:

  • 在设计时未明确设置的任何内容都必须在运行时设置。自动创建数据模块时使用该全局变量(请参阅项目设置中的自动创建表单或查看 .DPR)。如果您删除它并自动创建它,它将无法编译。要么将表单传递给数据模块中的方法,要么将数据模块传递给表单上的方法并将所有内容挂在那里。
  • 表单和数据模块都不是自动创建的,因此全局变量不是问题。从下面发布的答案 Mark 看来,问题出在组件流系统上。
  • 如果有问题,您应该在问题中说明。
  • 嗯...我做到了。如果您有解决方案,您应该将其发布为答案。
  • “看来问题出在组件流系统上”。您的问题中没有关于此“问题”或此“问题”与您的问题的关系:“是否有更简单的方法将第二个表单实例绑定到第二个数据模块的数据集,而无需手动编码 SomeControl.DataSource :=每个控件的 Module2.dsSomeData"。

标签: delphi data-binding delphi-2010


【解决方案1】:

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

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

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

【讨论】:

  • 不错的技巧,但它不会防止可能丢失的设计时间设置。
【解决方案2】:

我有一个表单,它的数据感知控件绑定到 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。这样数据控件 - 数据源绑定保持不变(因为两者都是从同一个 DFM 中读取的),并且只有数据源的数据集设置需要手动设置:

  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、字段等的 IDE 的所有设计时功能和智能...

【讨论】:

  • 是的,数据源当然位于控件和数据集之间。我假设任何有足够知识来回答这个问题的人都已经非常熟悉数据绑定如何工作的细节。遗憾的是,18 年后,他们仍然没有解决表单设计器在不同单元中的组件之间删除链接的问题。
  • 抱歉吹毛求疵。我相信你对 DataSources 了如指掌,但我觉得奇怪的是你从未在问题中提及它们,尤其是在你建议将 DataSets 移动到 Form 的地方。我现在了解到,默认情况下您将 DataSources 与 DataSets 一起保存。我想说的是,这并不是最好的策略。
【解决方案3】:

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

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

例如

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

TdmSachkonto 是我的 DataModule。

【讨论】:

  • 如果您有两个表单和一个 DataModule,那么您肯定不会遇到同样的问题!这不是问题的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-02
  • 2015-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-15
相关资源
最近更新 更多