我想知道为什么Delphi(2007)提供了三个似乎做同样事情的小部件,以及每个小部件的优点/缺点。
在同一主题上,如果我想显示不同的控件集,为什么我应该支持,例如。 PageControl + TabSheets + Frames,而不是直接在父窗体上显示不同的帧?
谢谢。
答案 0 :(得分:23)
来自TTabSet上的帮助文件:
标签集控件通常用于 在对话框中显示选项卡式页面 框。向后提供TTabSet 兼容性。使用TTabControl 32位Windows中的组件 应用
所以真正的问题是,TTabControl和TPageControl有什么区别?不同之处在于TTabControl只有一个“页面”,而TPageControl每个选项卡都有一个页面。这使它们在不同情况下有用。
TPageControl对于您希望在屏幕上放置比屏幕空间更适合的对话框非常有用。将UI组织成类别并将每个类别放在一个页面上。例如,您可以在“选项”对话框中看到很多这种模式。
另一方面,TTabControl适用于处理数组/对象列表。创建一个UI来显示和编辑单个对象的属性,并将其放在TTabControl上,然后为每个对象创建一个选项卡并设置事件处理程序,这样它就会在每次你将数组中的新对象加载到控件中改变标签。至于帧问题,将TPageControl与帧结合使用的主要原因是它提供了一种预先构建的方式来决定显示哪个帧。这样你就不必为它重新发明一种机制。
答案 1 :(得分:5)
我使用的一个非常成功的方法是使用带有TPageControl的帧,并在第一次选择页面时将我的帧后期绑定到tPageControl。这样可以缩短表单加载时间,不创建从未查看的帧,但允许创建的灵活性,在选项卡之间切换时保持状态。最近我转而使用表单并嵌入它们而不是框架......但概念是相同的。
使用TTabControl上的单个“挂载点”并在更改选项卡时将其切换出来也可以完成相同的操作,但随后也会出现如何处理选项卡状态作为选项卡切换回来的问题。 / p>
[编辑]问题出现了如何处理框架与父窗体之间的通信。这实际上很容易使用接口。只需创建一个将由表单和框架共享的新单元,并添加两个接口:
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;