TTabSet、TTabControl和TPageCtrl/TTabSheet之间的区别是什么?

17

我想知道为什么Delphi(2007)提供了三个似乎做同样事情的窗口部件,以及每个部件的优缺点是什么。

在同一话题上,如果我想显示不同的控件集,为什么应该选择例如PageControl + TabSheets + Frames,而不是直接在父窗体上显示不同的框架?

谢谢。

2个回答

25

来自TTabSet帮助文件:

选项卡集控件通常用于在对话框中显示选项卡页面。TTabSet提供向后兼容性。在32位Windows应用程序中使用TTabControl组件。

那么真正的问题是,TTabControl和TPageControl有什么区别?它们之间的区别在于TTabControl只有一个“页面”,而TPageControl每个选项卡都有一个页面。这使它们在不同的情况下非常有用。

TPageControl适用于想要在屏幕上放置更多UI而又没有足够空间的对话框。将您的UI组织成类别,并将每个类别放在一个页面上。例如,在“选项”对话框中经常看到这种模式。

另一方面,TTabControl适用于处理对象数组/列表。创建一个UI以显示和编辑单个对象的属性,并将其放置在TTabControl上,然后为每个对象创建一个选项卡,并设置事件处理程序,以便在更改选项卡时将新对象从数组加载到控件中。

至于框架问题,与框架结合使用TPageControl的主要原因是它提供了一种预构建的方式来决定要显示哪个框架。这样,您就不必重新发明一种机制。


谢谢Jim。因此,当在运行时填充选项卡中的对象时,TTabControl是首选解决方案,而PageControl + TabSheets + Frames则是在设计时设置UI的更好选择? - Gulbahar
3
一个TTabControl是编辑同一类型对象列表属性的首选方案,因为改变标签页并不会改变你所看到的控件,仅仅是改变了标签页索引。而一个页面控制器则是用于在一个窗体上同时放置多个超过一页的不同控件。 (Jim并没有写那个答案;是我写的。他只进行了编辑。) - Mason Wheeler
谢谢Mason,很有道理。对于我的需求来说,似乎PageControl加上一些选项卡页,每个选项卡页包含一个框架是我需要做的首选解决方案。 - Gulbahar

5
我曾经成功地采用的一种方法是使用带有 TPageControl 的框架,第一次选择该页面时,将我的框架绑定到 tPageControl 上。这样做可以使窗体加载时间缩短,因为不会创建未被查看的框架,但同时也允许创建,当在选项卡之间切换时状态得以保持。最近我改用表单并嵌入它们而不是框架...但概念是相同的。
可以使用 TTabControl 上的单个“安装点”,并在更改选项卡时进行切换,但这样做会引起如何处理选项卡状态的问题,因为选项卡也会切换回来。
[编辑]问题出现了,我如何处理框架和父窗体之间的通信。实际上,使用接口非常容易解决此问题。只需创建一个新的单元,该单元将由窗体和框架共享,并添加两个接口:
type
  IFormInterface = interface
    [guid]
    procedure FormProc;
  end;

  IFrameInterface = interface
    [guid]
    procedure SetFormController(Intf:IFormInterface);
  end;

让表单实现IFormInterface接口,让框架实现IFrameInterface接口。当您单击选项卡并显示一个框架时,运行以下代码:
var
  FrameIntf : IFrameInterface;
begin
  if Supports(FrameObj,IFrameINterface,FrameIntf) then
    FrameIntf.SetFormController(Self);
end;  

您的SetFormController方法的框架实现将保留传递的引用,以允许其向上调用表单。
procedure TFrame1.SetFormController(Intf:IFormInterface);
begin
  fFormController := Intf;
end;

Procedure TFrame1.Destroy; override;
begin
  fFormController := nil;  // release the reference
  inherited;
end;

Procedure TFrame1.Button1Click(Sender:tObject);
begin
  if fFormController <> nil then
    fFormController.FormProc
  else
    Raise Exception.Create('Form controller not set');
end;

谢谢你的建议。当您使用PageControl和多个框架时,您如何从父窗体中检查哪个按钮在哪个框架中被点击了呢? - Gulbahar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接