Articles   Members Online:
-Article/Tip Search
-News Group Search over 21 Million news group articles.
Member Area
-Account Center
-Top 10 NEW!!
-Submit Article/Tip
-Forums Upgraded!!
-My Articles
-Edit Information
-Become a Member
-Why sign up!
-Chat Online!
-Indexes NEW!!
-Build your resume
-Find a job
-Post a job
-Resume Search
-Link to us
Visit Embarcadero
Embarcadero Community
how to reorder a TPageControl at runtime Turn on/off line numbers in source code. Switch to Orginial background IDE or DSP color Comment or reply to this aritlce/tip for discussion. Bookmark this article to my favorite article(s). Print this article
Delphi 2.x
User Rating
No Votes
# Votes
DSP, Administrator
Reference URL:
			Author: Jonas Bilinkevicius

Let's say we have a TPageControl with 15 pages, the design time PageIndex of each 
page is 0 to 14 respectively. Now we want to change this order at runtime. The new 
order is saved in an *.ini file, the values for the new order is stored in an array 
of integer we will call MyOrder. Here is what the code would look like to change 
the order:

  i: Integer;

  for i := 0 to PageControl1.PageCount - 1 do
    PageControl1.Pages[i].PageIndex = MyOrder[i];

After executing this block of code the order of the pages is unchanged. Can you 
tell my why this doesn't work?


Solve 1:

Try this chunk of code. The key is that you set the 0th page index, then the 1rst, 
then the 2nd and so on. Since you're doing them in order, they don't get screwed up 
by later assignments.
2   procedure TForm1.ReorderBtnClick(Sender: TObject);
3   const
4     NewOrder: array[0..6] of Integer = (2, 0, 6, 1, 5, 3, 4);
5   var
6     X: Integer;
7     OrigPages: array of TTabSheet;
8   begin
9     {Keep an ordered list of tab sheets}
10    SetLength(OrigPages, 7);
11    for X := 0 to 6 do
12      OrigPages[X] := PageControl.Pages[X];
13    {Reorder tab sheets}
14    for X := 0 to 6 do
15      OrigPages[NewOrder[X]].PageIndex := X;
16    {Release ordered list of tab sheets}
17    OrigPages := nil;
18  end;

Solve 2:

This won't make order of the pages unchanged, but it won't give you the order you 
expect either. Remember that while you are re-ordering the pagecontrol, the 
pagecontrol also reorders itself. For example, you have a pagecontrol with 5 tabs, 
labelled One, Two, Three, Four and Five. If you try to reorder so that these pages 
move to the positions 3, 5, 1, 4, 2 respectively, then the order your code will put 
them in will be Four, Three, Two, One, Five because of the way they get reordered 
by the pagecontrol while you are moving them around.

Now, the really cool thing, and what seems to be happening to you, is that if you 
apply the exact same reordering (using your algorithm) as first used, the tabs will 
go back to the positions that they started from! Step through your code, and I'm 
sure your reordering routine will be called twice. To reorder them successfully, 
you would simply use a search and position algorithm, working from the last tab 
position back to the first to get around the pagecontrol's own re-ordering. I'm not 
sure from your post whether your array of positions is "for this position, this is 
the page that goes here" or "for this page, this is the position it should be in", 
so here is how to re-order your pagecontrol. We'll use the Tag property to let the 
page remember where it should be. Use only *one* of the first two commented 
for-loops, depending on your data structure.

19  { ... }
20  var
21    i, j: Integer;
22  begin
23    {Use this loop if the following describes your array:
24    "For this position (index), this is the page that goes here (contents)"
25    (that is, the contents of the array is the current pageindex, and the array
26    index is the new pageindex for that page)}
28    for i := 0 to PageControl1.PageCount - 1 do
29      PageControl1.Pages[MyOrder[i]].Tag := i;
31    {OR use this loop if the following describes your array:
32    "For this page (index), this is the position it should be in (contents)"
33    (That is, the array index corresponds to the current pageindex, and the contents
34    of the array is the new pageindex that page should have)}
36    for i := 0 to PageControl1.PageCount - 1 do
37      PageControl1.Pages[i].Tag := MyOrder[i];
39    {Then simply reorder the pagecontrol}
40    for i := PageControl1.PageCount - 1 downto 0 do
41      for j := 0 to i do
42        if PageControl1.Pages[j].Tag = i then
43        begin
44          PageControl1.Pages[j].PageIndex := i;
45          Break;
46        end;
47  end;

One of the two will work for you.

Solve 3:

The correct method to disconnect tabsheets and reconnect them:

48  { ... }
49  var
50    I: Integer;
51    L: TList;
52  begin
53    L := TList.Create;
54    try
55      {This just disconnects - you should replace this with your code to disconnect 
56  		them in the order you want to reconnect them}
57      for I := PageControl1.PageCount - 1 downto 0 do
58      begin
59        L.Add(PageControl1.Pages[I]);
60        PageControl1.Pages[I].PageControl := nil;
61      end;
62      {Reconnect...}
63      for I := 0 to L.Count - 1 do
64        TTabSheet(L[I]).PageControl := PageControl1;
65    finally
66      L.Free;
67    end;
68  end;

Vote: How useful do you find this Article/Tip?
Bad Excellent
1 2 3 4 5 6 7 8 9 10


Share this page
Download from Google

Copyright © Mendozi Enterprises LLC