Forum > Designer

[solved] How to arrange tabs of a TPageControl

<< < (2/2)

wp:
Two solutions:

By default the width of a tab is determined by the length of the caption. By using the TabWidth property it can be adjusted to any width. The trick here is to adjust the TabWidth such that it stretches over half of the ClientWidth of the parent - this way the PageControl can accomodate only two tabs per row and then must wrap the next tabs into the next row (provided that the Multiline options is active). When you put this code into the OnResize event handler of the PageControl's parent, this layout of two tabs per row will be independent of the pagecontrol's Width:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TForm1.FormResize(Sender: TObject);  // For PageControl directly on the formbegin  PageControl1.TabWidth := (ClientWidth - 10) div 2;  // 10 subtracted for some unknown marginsend;A disadvantage is that multi-lined Pagecontrol are not supported in all widgetsets...

Another solution combines some controls to a "faked" pagecontrol - well, you will have to accept something which does not look exactly like a TPageControl, but it serves the same purpose:

* Drop a panel on the form (or the parent which will contain the pagecontrol). Select Align = alTop.

* Drop four speedbuttons on this panel, place them anywhere
* Go to property "ChildSizing" of the panel, set its "Layout" to "cclLeftToRightThenTopToBottom" and "ControlsPerLine" to 2 - now the speedbuttons are arranged nicely in two rows.
* Drop a TNotebook on the form (or the parent of the "faked" pagecontrol). Set Align = alClient. Like a TPageControl, a TNotebook can have several pages, but there are no tabs. Therefore, you need the Speedbuttons - they serve as tabs...
* Right-click on the TNotebook and add four pages - you will not see the pages in the designer form, but in the object tree. For adding controls to each page, select it first in the object tree.
* Now return to the speedbuttons and specifiy in the "Tab" "Tag" property the index of the notebook page associated with the button.
* Write the following handler and assign it to each speedbutton's OnClick event:
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TForm1.SpeedButton1Click(Sender: TObject);begin  Notebook1.PageIndex := (Sender as TSpeedButton).Tag;end;
To give you idea what this looks like I am attaching a simple dummy project with both solutions.

Muso:

--- Quote from: wp on August 18, 2025, 06:20:45 pm ---By default the width of a tab is determined by the length of the caption. By using the TabWidth property it can be adjusted to any width. The trick here is to adjust the TabWidth such that it stretches over half of the ClientWidth of the parent - this way the PageControl can accomodate only two tabs per row and then must wrap the next tabs into the next row (provided that the Multiline options is active)...

--- End quote ---

many thanks! This works well (I only need it for LCL under Windows).

However, I found this way a bug: https://gitlab.com/freepascal.org/lazarus/lazarus/-/issues/41801

n7800:

--- Quote from: wp on August 18, 2025, 06:20:45 pm ---
* Now return to the speedbuttons and specifiy in the "Tab" property the index of the notebook page associated with the button.
* Write the following handler and assign it to each speedbutton's OnClick event:
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TForm1.SpeedButton1Click(Sender: TObject);begin  Notebook1.PageIndex := (Sender as TSpeedButton).Tag;end;
--- End quote ---

@wp, I think you meant to write "Tag" and not "Tab"?

wp:
Yes, of course.

n7800:
Then maybe edit the post? I'm sure someone else will find this thread and want to use this method.

EDITED: Thanks )

Navigation

[0] Message Index

[*] Previous page

Go to full version