如何在设计时处理多个 TPanel?

6

我的主窗体上有几个TPanel,根据用户选择的选项显示/隐藏。问题在于,在设计时,我必须不断地移动它们才能对它们进行编辑。有没有更简单/更好的方法来处理这种情况?

7个回答

10
如果一次只能显示一个面板,那么你可能想使用 TPageControl 来组织内容。在设计时,您可以单击选项卡来选择要处理的页面,然后在运行时隐藏选项卡,或者始终隐藏选项卡并通过设置 ActivePage 属性 来选择页面。

1
赞同这个观点。这是更好的控件组织方式。如果您不需要选项卡标题,可以创建自己的派生类,或使用已经开发好的,并在运行时将Tabheight设置为0。 - Simon
是的,@David,这绝对是这个的一个副作用。不过我并不认为这是什么大问题,因为可调整大小的表单、锚点和对齐方式一直使它与我设计的任何表单无关。 - Rob Kennedy
@Rob 这完全取决于情况。我的很多表单都是不可调整大小的表单。 - David Heffernan
@david,在对象检查器中使用activepage属性。 - Jørn E. Angeltveit
@Jørn 不错。你应该编辑Rob的答案,也包括这个选项。 - David Heffernan
显示剩余3条评论

5
使用结构窗格查找您想要的内容,然后将其置于前面。 结构窗格 (来源:embarcadero.com) (但不要像Embarcadero上面的例子那样,给您的控件起有意义的名称,这样更容易区分您的控件。)

1
+1;我最喜欢的方式是完全重叠的控件。您只需选择该项,右键单击并按下O + F键即可将控件置于前面。 - user532231

3

在运行时将Panel1.Visible设置为false时,我发现一个注意事项是它会影响布局。
我找到的解决方案是:

//Design time
//-----------
Panel1.BevelOuter:= bvNone; //Make the panel look flat.

//Run time when hiding the panel
//------------------------------
procedure HidePanel(APanel: TPanel);
var
  H,W: integer;
begin
  case APanel.Align of 
    alTop, alBottom: begin
      APanel.Tag:= Max(APanel.Tag, APanel.Height);
      APanel.Height:= 1;
    end; {alTop, alBottom:}
    alLeft, alRight: begin
      APanel.Tag:= Max(APanel.Tag, APanel.Width);
      Panel1.Width:= 1;
    end; {alLeft, alRight:}
    alNone: begin
      H:= Max(APanel.Tag and $FFFF, APanel.Height);
      W:= Max((APanel.Tag shl 16) and $FFFF0000, APanel.Width shl 16);
      APanel.Tag:= (H or W);
      APanel.Height:= 1;
      APanel.Width:= 1;
    end; {alNone} 
    //alClient: do nothing
  end;
end;

//Run time when restoring the panel
//---------------------------------
procedure UnhidePanel(APanel: TPanel);
var
  H,W: integer;
begin
  case APanel.Align of 
    alTop, alBottom: begin
      APanel.Height:= APanel.Tag;  
      APanel.Tag:= 0;
    end; {alTop, alBottom:}
    alLeft, alRight: begin
      APanel.Width:= APanel.Tag;
      APanel.Tag:= 0;
    end; {alLeft, alRight:}
    alNone: begin
      H:= APanel.Tag and $FFFF;
      W:= APanel.Tag shr 16;
      APanel.Height:= H;
      APanel.Width:= W;
      APanel.Tag:= 0;
    end; {alNone}
    //alClient: do nothing
  end; {case}
end;

简单地隐藏面板可能会破坏您在设计时构建的精细对齐方式(特别是在使用分隔器时)。这段代码可以防止这种情况发生。当面板没有设置斜面和面板颜色等于其所在控件的颜色时,它在视觉上才真正起作用。


3

如果面板被堆叠,您可以右键单击其中一个并从上下文菜单中选择控制->置于顶部控制->置于底部来重新排序它们。


2

我使用对象检查器组合框选择框架或面板,然后在主菜单中点击"编辑" --> "置于顶部"

(这类似于打开结构视图)


1
我也使用过TPageControl,并在设计时保持选项卡可见。这使得我可以在设计时通过单击所需的选项卡来使用它。然后在运行时,我隐藏了页面选项卡,并使用代码切换页面控件上的活动页面,以切换可见的窗格。然而,这导致了一些非常庞大和复杂的表单,反过来又引起了许多问题。
对于您的情况,我建议您考虑将每个窗格重构为自己的表单或框架。我的首选是使用表单,而不是框架,原因在Delphi世界中已经广为人知并有充分的文献记录。
在我最好结构化的应用程序中,每个“窗格”(使用TForm实现,而不是TFrame)都分别放在不同的单元中,这解决了您的设计时控制问题,并且还产生了更好结构化的整体解决方案。

我认为结构面板(如其他人所指出)对你来说是一个很好的帮助。但是,当你想处理复杂度超过常规设计视觉工具的表单时,考虑将表单拆分,并在使用表单设计器时达到“收益递减”点时,这也是一个不错的想法。因为表单变得越来越复杂。


1

使用框架实现这个目的要容易得多。我通常在运行时创建它们,并根据需要将它们添加到表单中。这也使代码更易读,因为您可以在不同的框架上使用相同的组件名称(例如 ed_Name 或 l_Welcome),而无需使用诸如 ed_NameForPanel1、ed_NameForPanel3 等名称来避免名称冲突。


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