Languages :: Delphi :: TPageControl click |
|||
| By: VB guy |
Date: 07/02/2003 00:00:00 |
Points: 25 | Status: Answered Quality : Excellent |
|
How can I find out what tab was clicked in the OnChanging event so I can determine if I want to allow access to that page? Thanks. VBG |
|||
| By: VGR | Date: 07/02/2003 08:28:00 | Type : Answer |
|
| PageControl1.ActivePage.TabIndex (I guess it starts from 0) |
|||
| By: sumotimor | Date: 07/02/2003 08:51:00 | Type : Comment |
|
VGR, That will give the current page, not the page that is going to be active next. Avi, Unfortunately, the OnChanging event (which got fired from a WM_NOTIFY message containing TCN_SELCHANGING) does not contain the index of the tab that WILL BE made active. It won't be until after the OnChange fires that the ActiveTabIndex can tell you this, then it's too late. You might rethink this; perhaps by disabling the tabs that should not be allowed to be made active at the current state in your program. sumotimor |
|||
| By: VB guy | Date: 08/02/2003 16:00:00 | Type : Comment |
|
| The problem is that when a TabSheet enabled property is set to false, its content is still displayed when the user selects the disabled tab. The only way around that is to set the Visible property of a TabSheet to False, but that looks rather strange. It would have been much nicer if it was possible to trap the click event for the tab the user is trying to access and at that point make the decision. or better yet if the enabled state of the tab simply grayed it out and not respond to user clicks... Any suggestions? VBG |
|||
| By: VGR | Date: 08/02/2003 18:12:00 | Type : Comment |
|
| I don't agree in my program (D4.01), in the OnChanging event handler of the TPageControl component, I do : -memory operation of the current "page"(tab) to save it With gPages[locNumPage] Do. -loading the desired page(tab) via LoadPage(PageControl1.ActivePage.TabIndex+1) and it works, so... I'll just show you the procedure that does LoadPage(index), perhaps it'll help you : Procedure ChargePage(index : Word); // numéro DE LA PAGE (=index +1) Var j : Byte; i : Integer; //VGR25082002 fond en clair Begin If (index=0) Then locNumPage:=1 Else locNumPage:=index; If locNumPage>gPnb Then // initialisation page locNumPage Begin //traces // ShowMessage('initialisation page '+IntToStr(locNumPage)); // With gPages[locNumPage] Do Begin NbImages:=0; codetype:=gAtype; nbi:=gAnbi; nbl:=gAnbl; codecadre:=gAvalcadre; codefond:=gAvalfond; For j:=1 to cMaxImgPage Do indexFichiers[j]:=0; End; Inc(gPnb); locNumPage:=gPnb; If (locNumPage<>1) Then // cas particulier (onglet toujours créé à l'init.) Begin With TTabSheet.Create(Etape3.PageControl1) do Begin PageControl := Etape3.PageControl1; Name := 'ts' + IntToStr(locNumPage); Caption := 'page' + IntToStr(locNumPage); PopUpMenu := Etape3.PopupMenu2; End; Inc(globNbTabs); //traces // ShowMessage('ajout page '+IntToStr(locNumPage)); // End; // création nouvel onglet Etape3.PageControl1.ActivePage:=Etape3.PageControl1.Pages[locNumPage-1]; Etape3.Panel1.Parent:=Etape3.PageControl1.ActivePage; End Else Begin // chargement normal //traces // ShowMessage('mémorisation de page '+IntToStr(locNumPage)); // //VGR070602 ADDed code de non-création si existe en mémoire If locNumPage>globNbTabs Then Begin With TTabSheet.Create(Etape3.PageControl1) do Begin PageControl := Etape3.PageControl1; Name := 'ts' + IntToStr(locNumPage); Caption := 'page' + IntToStr(locNumPage); PopUpMenu := Etape3.PopupMenu2; End; Inc(globNbTabs); End; Etape3.PageControl1.ActivePage:=Etape3.PageControl1.Pages[locNumPage-1]; Etape3.Panel1.Parent:=Etape3.PageControl1.ActivePage; End; // init ou chargement // positionnement des contrôles (si modifiable ;-) Etape3.ListBox2.ItemIndex:=gPages[locNumPage].codetype; cSpinChange:=False; Etape3.SpinEdit1.Value:=gPages[locNumPage].nbl; Etape3.SpinEdit2.Value:=gPages[locNumPage].nbi; cSpinChange:=True; //VGR25082002 MODification des fonds, plus d'index (noms de fichier en clair) //was : Etape3.ComboBox1.ItemIndex:=gPages[locNumPage].codefond; i:=-1; Repeat Inc (i); Until Etape3.ComboBox1.Items=TrueFileName(gPages[locNumPage].codefond); Etape3.ComboBox1.ItemIndex:=i; //EoMod Etape3.ComboBox2.ItemIndex:=gPages[locNumPage].codecadre; If gPages[locNumPage].codetype=0 Then Begin Etape3.SpinEdit1.Enabled:=True; Etape3.SpinEdit2.Enabled:=True; Etape3.Label7.Enabled:=True; Etape3.Label8.Enabled:=True; Etape3.Label1.Enabled:=True; Etape3.SpinEdit1.SetFocus; End Else Begin Etape3.SpinEdit1.Enabled:=False; Etape3.SpinEdit2.Enabled:=False; Etape3.Label7.Enabled:=False; Etape3.Label8.Enabled:=False; Etape3.Label1.Enabled:=False; End; // retracé Retrace; End; // ChargePage Procedure |
|||
| By: sumotimor | Date: 10/02/2003 09:41:00 | Type : Comment |
|
VGR, On D3, the following code procedure TForm1.PageControl1Changing(Sender: TObject; var AllowChange: Boolean); begin ShowMessage(IntToStr(PageControl1.ActivePage.TabIndex)); end; ends up showing the current page index, not the newly selected page index. On D5, procedure TForm1.PageControl1Changing(Sender: TObject; var AllowChange: Boolean); begin ShowMessage(IntToStr(PageControl1.ActivePage.TabIndex)); ShowMessage(IntToStr(PageControl1.ActivePageIndex)); end; both return the current page as well. I can't say with D4 as I don't have that version... Avi, One "hack" around this is to allow the OnChanging to fire (allow the change), and then you can determine if the change should be allowed in the OnChange event. But, you don't want the user to see the tabs change back/forth during this, so perform a lockwindowupdate() on the page control (WM_SETREDRAW would be preferred, but unfortunately does not work on this control). The key to this working is the fact that setting ActivePageIndex does NOT fire an OnChanging/OnChange event, so setting the ActivePageIndex to the old page will not cause this to fire recursively. Note: In the example below I used the Tag property to store the old page index, keep it or use your own state variable. procedure TForm1.PageControl1Changing(Sender: TObject; var AllowChange: Boolean); begin // Save off state and allow change to go through with (Sender as TPageControl) do begin Tag:=ActivePage.TabIndex; LockWindowUpdate(Handle); end; end; procedure TForm1.PageControl1Change(Sender: TObject); begin // Determine if we should allow change with (Sender as TPageControl) do begin // Example of disallowing change when the selected // page index was 0 or 2 if (ActivePage.TabIndex in [0, 2]) then ActivePage:=Pages[Tag]; // Update the page control LockWindowUpdate(0); Invalidate; end; end; The last note in regards to handling tabs this way is that keyboard tab page switching gets broken. Meaning, using the right/left arrow key will work until it hits a tab that you don't allow access on. Remember, the OnChanging was actually designed to stop focus from leaving a tab, not for determining if focus should/should not be allowed on a specific tab. sumotimor |
|||
| By: VGR | Date: 10/02/2003 09:48:00 | Type : Comment |
|
| I'm using D4 for that project. Did not test it under an other compiler. Strange that such things do vary ;-) |
|||
|
Do register to be able to answer |
|||
©2010 These pages are served without commercial sponsorship. (No popup ads, etc...). Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE.
Please DO link to this page!








