2

我的主窗体中有一个列表视图,我希望另一个非模态窗体能够添加内容。我如何将列表视图传递给非模态表单?我希望能够修改它的表单由 MainForm 在单击按钮时显示,只需使用 Form.Show。

我还应该澄清一下,我希望表单不使用主表单以避免循环引用。

4

3 回答 3

2

注意:该问题最初标记为 Delphi。我不知道 FPC/Lazarus,所以下面的一些细节可能不准确,但这些概念仍然有效。


我猜你有一个代表主要形式的全局变量,MainForm为了论证而命名。最快和最简单的方法是简单地使用MainForm.ListView让您的其他表单引用主表单的列表视图。

我对这种方法并不十分热衷,因为这意味着另一种形式依赖于主形式的实现。


作为替代方案,您可以将对列表视图的引用传递给其他表单。例如,您可以SetListView在其他表单中添加一个过程:

type
  TMyOtherForm = class(TForm)
  private
    FListView: TListView;
  public
    procedure SetListView(Value: TListView);
  end;
.....
procedure TMyOtherForm.SetListView(Value: TListView);
begin
  FListView := Value;
end;

然后在主窗体中,可能在主窗体的OnCreate事件处理程序中,您可以调用此方法:

procedure TMainForm.FormCreate(Sender: TObject);
begin
  MyOtherForm.SetListView(ListView);
end;

这并不比第一个建议好多少。另一种形式仍然依赖于主要形式的实现,尽管可以说是一种不太重要的依赖关系。


如果您想让这两个表单的耦合度更低,那么主表单可以公开一个接受添加到列表中的方法:

procedure TMainForm.AddToList(const Name: sting; const Time: TDateTime);
var
  Item: TListItem;
begin
  Item := ListView.Items.Add;
  Item.Caption := Name;
  Item.SubItems.Add(DateTimeToStr(Time));
end;

在您的其他表单单元中,您将主表单单元添加到实施部分的使用子句中。这允许您访问MainForm全局变量,您可以调用

MainForm.AddToList(Name, Time);

这种方法在我看来是最好的,因为它允许主窗体将其列表实现保持为自己私有。


您在评论中声明您希望避免由于uses子句引起的任何循环引用。这很容易安排,因为上述任何一项都不需要修改uses来自两个单元的接口部分的子句。

于 2012-04-10T19:21:06.680 回答
2

最简单和最好的方法是向接收表单添加一个方法——即上面带有 ListView 的表单——上面写着“AddThingsToListView”,并让它接受你想要添加的东西(可能是一个 TListItem?)

这样,您就可以调用

MyMainForm.AddThingsToListView(ANewListItem);

从任何地方。

换句话说,不要将列表视图传递给非模态表单;相反,让主窗体能够接受对其列表视图的添加。

于 2012-04-10T19:24:57.833 回答
0

我做什么:对于这种情况:我通常声明一个数据模块,并将大部分不适合非GUI库单元的代码放入数据模块中。数据模块可以引用表单,反之亦然,但没有一个表单相互引用。

在此示例中,您的 Form2 可以使用 DataModule,您可以执行以下任一操作:

  1. 在数据模块中有一个对 MainForm 的 ListView 的全局引用,并从您的表单中使用它。
  2. 在数据模块中有一个函数/类,可让您更新列表,并从表单中调用它。

无论哪种方式,您的表单只需要知道数据模块,其余的由数据模块完成。您可以添加/删除/更改表单,通常您只需更新 DM。

于 2012-08-13T02:22:28.633 回答