德尔福,框架与形式。什么是多文档界面?

时间:2009-09-23 08:47:23

标签: delphi mdi frames tframe

昨天我开始讨论“MDI vs tabbed interface”。我已经问过我是否应该继续开发基于MDI的应用程序,或者我应该将子表单嵌入到标签页中。 有人指出我应该使用TFrame代替......我的问题是:为什么?

在TFrame上嵌入表单时使用TFrame的优点是什么?到目前为止我不知道,切换只需要我重写代码的某些部分......

(我不打算在设计时使用嵌入!)

提前致谢

7 个答案:

答案 0 :(得分:11)

回答评论以提供使用框架的原因:

我认为框架是GUI的构建块,现有组件的设计时间组合到更高级的组件。在Delphi 5之前,人们会使用带有子控件的TCustomPanel后代,并将其注册为新组件,准备将其放到表单上。框架允许同样的事情,减少麻烦。

它们使您可以专注于开发所需的功能,仅此而已。完成后,您可以将它们嵌入到选项卡控件页,模态或无模式对话框,MDI子框架和标准框架中。您甚至可以将其中的几个添加到一个表单中 - 这可能与嵌入表单无关。关键在于,为了获得最大的可重用性,通常需要采用分层方法,并且框架可以帮助实现这一点。

框架适合从中进行嵌入。表单必须适应不显示标题栏和边框,通常会覆盖CreateParams()并相应地调整窗口样式。检查器中有很多表单属性,对嵌入表单没有意义。恕我直言,应该使用最基本和最通用的实体。表单不仅仅是用于嵌入的控件容器。

OTOH我不知道嵌入一个没有嵌入表单的框架会有什么不利之处。

修改

有关框架没有的OnCreateOnShow等事件的评论。实际上,我认为帧的另一个优点是,因为事件处理程序没有参数,所以很多东西都必须在表单中进行硬编码。

考虑每个用户设置的情况:在OnCreate中没有太多可用的信息,因此总是最终使用常量或INI文件部分的表单名称,使其非常难或甚至不可能重用表单或创建它的几个实例。另一方面,使用框架LoadSettings方法是明显的方法,它可以携带必要的参数。这样控制就返回到它所属的位置,返回到嵌入式框架/表单的容器。只有在可以从外部调整行为时才可以使用可重用性。

对于非组件且需要进行终身管理的包含对象,例如AfterConstructionBeforeDestruction

答案 1 :(得分:5)

也许你会在这个帖子中找到一些答案:gui-design-multiple-forms-vs-simulated-mdi-tabs-vs-pagecontrol

答案 2 :(得分:2)

帧在创建帧时使用最快的负载并且没有延迟。

但框架应该有一个嵌入它的父级。没有触发onCreate或onShow事件的缺点。但是您可以使用消息来调用触发onShow事件,如下所示:

加上框架的私人部分:

procedure CMShowingChanged(var M: TMessage); message CM_SHOWINGCHANGED;

然后创建如下代码:

procedure TFrame1.CMShowingChanged(var M: TMessage);
begin
  inherited;
  if Showing then
  begin
    // .... put your code for onShowing is triggered
  end
  else
  begin
    // .... put your code for onHiding is triggered
  end;
end;

希望可以帮助您考虑GUI的嵌入式框架。

您可以考虑与PageControl结合使用来控制您的画面开启。

曼茨

答案 3 :(得分:1)

我几年前就我们的一个应用程序做了同样的决定,我们想让它看起来像嵌入式表格,首先我使用了Frames,然后我写了一个类来管理它。

后来我从LMDTools找到了TLMDDisplayForm组件,这使得在其中嵌入表单变得非常容易,它减少了使用的代码,我们有更多的功能。

我们从框架更改为Forms的主要目标之一是缺少TForm的一些事件:OnCreate,OnShow,OnActive我们在应用程序中用于某些任务,除了缺少一些属性,例如:ActiveControl和其他我不喜欢的东西不记得了。

如果您想使用表单,我建议您使用LMDTools使您更轻松地完成任务,除了基本版本免费: - )

答案 4 :(得分:1)

对于动态插入的表单/框架,我个人更喜欢在框架上使用嵌入表单。当一个人编辑设置为alClient的帧时,会返回几个版本,帧会在编辑之间调整大小,任何特定于帧右侧对齐的控件都会改变位置。当使用嵌入式表格时,这没有发生,所以我进行了切换。我相信这个问题现在已经解决了以后版本的Delphi。

我非常同意Mghie之前提出的关于无法通过通知事件将信息传递给嵌入表单的观点。为了解决这个问题,我通常在每种嵌入形式中实现一系列接口以进行通信。这确实简化了代码,并且允许更多通用实现,其中您有一个单独的“容器”,它将处理许多不同类型的嵌入式表单/框架。我的blog提供了一些这方面的例子,作为我设计的向导框架的一部分。

答案 5 :(得分:0)

我认为两者都应该被使用。例如,我有一个“标准”框架,它有一个dbnavigator,dbgrid和datasource组件,这对于典型的数据浏览非常方便。我不是每次都插入这样的组件,而是插入一个框架,它也能够将其数据(使用JVCL:D)导出为多种格式......但我知道我想在设计时显示什么,所以我建议一个简单规则:如果在设计时已知,请使用框架,否则使用嵌入式表格。

但是,请记住,表单并非旨在嵌入。像这样使用它们,它不自然(作为吸血鬼说她埋葬了她80岁的女儿,她看起来像30:D)。嵌入的表单几乎不了解拥有它的那个,也可以(逻辑上)假设它没有嵌入。

补充一点,框架是一个组件,因此,当在表单中嵌入(拥有)时,表单知道它并且框架知道表单(可以使用它的方法和属性。嵌入的一个也可以这样做但需要额外的编码)

也许Embarcadero可以通过为此目的创建一个TEmbeddableForm或界面来帮助我们。

此致 Alvaro Castiello

答案 6 :(得分:-1)

当您想在表单中多次重复“子表单”时,帧很好。我不会将它们用于标签式接口,因为嵌入式表单是MDI / Tabbed接口使用的更好解决方案。