IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Delphi Discussion :

Rendre un onglet inaccessible.


Sujet :

Delphi

  1. #1
    Membre éprouvé Avatar de defluc
    Homme Profil pro
    Architecte
    Inscrit en
    Mai 2002
    Messages
    1 383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    Localisation : Belgique

    Informations professionnelles :
    Activité : Architecte

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 383
    Par défaut Rendre un onglet inaccessible.
    Salut delphistes

    Je voudrais rendre un onglet inaccessible, voire invisible, si une certaine condition est remplie.

    Aucune des instructions suivantes ne donne de résultat.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    If Condition then  TabSheet4.Enabled := False
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    If Condition then  PageControl1.Pages[4].Enabled := False
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    If Condition then  TabSheet4.Visible := False
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    If Condition then  PageControl1.Pages[4].Visible := False
    Cette opération est-elle réellement impossible ?

    Merci d'avance

  2. #2
    Membre Expert
    Avatar de Clorish
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 474
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 474
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Self.PageControl1.Pages[i].TabVisible := false

  3. #3
    Membre éprouvé Avatar de defluc
    Homme Profil pro
    Architecte
    Inscrit en
    Mai 2002
    Messages
    1 383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    Localisation : Belgique

    Informations professionnelles :
    Activité : Architecte

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 383
    Par défaut
    Ok, cela fonctionne.
    Mais je préfèrerais garder l'onglet visible mais grisé ("not enabled").
    Est-ce possible ?

  4. #4
    Membre Expert
    Avatar de Clorish
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 474
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 474
    Par défaut
    visiblement non

  5. #5
    Membre éprouvé Avatar de defluc
    Homme Profil pro
    Architecte
    Inscrit en
    Mai 2002
    Messages
    1 383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    Localisation : Belgique

    Informations professionnelles :
    Activité : Architecte

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 383
    Par défaut
    Regrettable.
    La compilation ne devrait pas laisser passer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    PageControl1.Pages[4].Enabled := False;

  6. #6
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Par défaut
    Citation Envoyé par defluc
    Regrettable.
    La compilation ne devrait pas laisser passer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    PageControl1.Pages[4].Enabled := False;
    Si tu fais ça, ça compile? Si oui est-ce que tu peux sélectionner l'onglet 4? Si non, il te suffit alors de redessiner toi-même uniquement le(s) tab(s) inactif(s) avec OnDrawTab
    Pedro
    Aucune réponse aux sollicitations techniques par MP

    Faut pas attendre d'en avoir besoin pour s'en servir... (Lucien Stéphane)

    Les pages Source C'est bon. Mangez-en!
    Le défi Delphi
    Règles du forum - FAQ Delphi - Pensez au chtit
    Aéroclub Bastia Saint-Exupéry

  7. #7
    Membre éprouvé Avatar de defluc
    Homme Profil pro
    Architecte
    Inscrit en
    Mai 2002
    Messages
    1 383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    Localisation : Belgique

    Informations professionnelles :
    Activité : Architecte

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 383
    Par défaut
    Ce qui est inexplicable, c'est que malgré l'exécution de l'instruction en question, l'onglet reste accessible.

  8. #8
    Membre confirmé
    Inscrit en
    Juin 2005
    Messages
    207
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 207
    Par défaut
    Ce qui peut signifier tout simplement que la méthode est surchargée, et que la propriété n'a pas été supprimée?

    En tout cas, je ne connaissais pas le coup du Self.PageControl1.Pages[i].TabVisible := false, je crois que ça va bien me servir!

  9. #9
    Membre expérimenté
    Profil pro
    DEV
    Inscrit en
    Août 2006
    Messages
    182
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : DEV

    Informations forums :
    Inscription : Août 2006
    Messages : 182
    Par défaut
    AS tu essayé la fonction CanShowTab ?

  10. #10
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Par défaut
    Citation Envoyé par defluc
    Ce qui est inexplicable, c'est que malgré l'exécution de l'instruction en question, l'onglet reste accessible.
    Mmmh... Effectivement c'est étrange... Tu as regardé dans les sources de la VCL si cette propriété était prise en compte lorsqu'un onglet était cliqué? Si non alors, tu pourrais faire un nouveau compo qui hérite de TPageControl dans lequel seule la méthode Change serait surchargée
    Sinon la méthode cracra: Dans Onchange, tu testes quel onglet devient actif et si c'est un onglet désactivé, tu reviens sur l'ancien... Mais bon
    Pedro
    Aucune réponse aux sollicitations techniques par MP

    Faut pas attendre d'en avoir besoin pour s'en servir... (Lucien Stéphane)

    Les pages Source C'est bon. Mangez-en!
    Le défi Delphi
    Règles du forum - FAQ Delphi - Pensez au chtit
    Aéroclub Bastia Saint-Exupéry

  11. #11
    Membre éprouvé Avatar de defluc
    Homme Profil pro
    Architecte
    Inscrit en
    Mai 2002
    Messages
    1 383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    Localisation : Belgique

    Informations professionnelles :
    Activité : Architecte

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 383
    Par défaut
    Pour le moment, c'est ce que je fais, Pedro.
    Mais ce serait plus élégant si l'intitulé de l'onglet pouvait apparaître en grisé.

    DragonHeart,
    je trouve «CanShowTab» dans l'aide comme méthode de TPage Control. Mais si je code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    PageControl4.CanShowTab := False;
    à la compilation, j'ai le message d'erreur
    Identificateur non déclaré : CanShowTab
    .

  12. #12
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Par défaut
    Citation Envoyé par defluc
    Pour le moment, c'est ce que je fais, Pedro.
    Mais ce serait plus élégant si l'intitulé de l'onglet pouvait apparaître en grisé.
    Tu fais quoi? l'interception dans OnChange ou bien le TDeflucPageControl?
    Si c'est le nouveau compo, tu peux aussi surcharger la méthode DrawTab pour redessiner les tabs correctement
    Pedro
    Aucune réponse aux sollicitations techniques par MP

    Faut pas attendre d'en avoir besoin pour s'en servir... (Lucien Stéphane)

    Les pages Source C'est bon. Mangez-en!
    Le défi Delphi
    Règles du forum - FAQ Delphi - Pensez au chtit
    Aéroclub Bastia Saint-Exupéry

  13. #13
    Membre éprouvé Avatar de defluc
    Homme Profil pro
    Architecte
    Inscrit en
    Mai 2002
    Messages
    1 383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    Localisation : Belgique

    Informations professionnelles :
    Activité : Architecte

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 383
    Par défaut
    Oui, je fais l'interception dans OnChange.

    Avant de m'atteler à créer un nouveau composant, je teste toutes les suggestions, dont celle du «CanShowTab».

  14. #14
    Expert confirmé
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Par défaut
    Salut

    Pour autoriser/interdire la sélection d'un onglet tu peux t'inspirer de ce code posté il y a quelques temps ici. (Post #8).

    Quant à griser l'onglet OnDrawTab devrait faire l'affaire.

    @+ Claudius

  15. #15
    Membre éprouvé Avatar de defluc
    Homme Profil pro
    Architecte
    Inscrit en
    Mai 2002
    Messages
    1 383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    Localisation : Belgique

    Informations professionnelles :
    Activité : Architecte

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 383
    Par défaut
    Merci Cl@udius mais je ne sais pas si ta solution apporte plus que celle que j'ai utilisée.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    procedure TMainForm.ChangeOnglet(OldOnglet:Integer);  // OldOnglet a la valeur index
    begin                                                 // de l'onglet quitté
      Case PageOnglet.ActivePage.PageIndex of
        0..3: begin
           //Code
           end;
        4: begin
           if not CadRevenuCheckBox.Enabled then
              PageOnglet.ActivePage := PageOnglet.Pages[OldOnglet];
           end;
        5: begin
           //Code
           end;
    end;

  16. #16
    Membre expérimenté
    Profil pro
    DEV
    Inscrit en
    Août 2006
    Messages
    182
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : DEV

    Informations forums :
    Inscription : Août 2006
    Messages : 182
    Par défaut
    Désolé de ma réponce tardive ... mais le CanShowTab est une méthode protégée
    tiré de l'aide
    Appelez CanShowTab pour déterminer si on peut sélectionner ou accéder à un onglet. CanShowTab est exposée en tant que méthode protégée afin que les descendants puissent la surcharger pour fournir un critère spécifique à l'application déterminant si un onglet est accessible.

  17. #17
    Membre émérite
    Avatar de CapJack
    Homme Profil pro
    Prof, développeur amateur vaguement éclairé...
    Inscrit en
    Mars 2004
    Messages
    624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Prof, développeur amateur vaguement éclairé...
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 624
    Par défaut
    Citation Envoyé par defluc
    Regrettable.
    La compilation ne devrait pas laisser passer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    PageControl1.Pages[4].Enabled := False;
    Mais bien sûr que si ! Par cette instruction, c'est la page qui est désactivée, pas l'onglet !

    Regarde bien : après une telle instruction, le TabSheet index 4 sera visible, mais désactivé ! S'il contient des boutons, on ne pourra pas cliquer dessus !

    J'ai l'impression qu'il y a confusion entre l'onglet et la page, les onglets malheureusement ne peuvent pas être désactivés (ce n'est tout simplement pas prévu par Windows, je viens de jeter un œil sur msdn) , mais les pages associées, si.

    D'un point de vue IHM, ça peut se défendre : l'utilisateur peut sélectionner la page pour voir ce qu'elle contient, mais ne peut pas agir dessus tant qu'elle est désactivée.

  18. #18
    Membre émérite
    Avatar de CapJack
    Homme Profil pro
    Prof, développeur amateur vaguement éclairé...
    Inscrit en
    Mars 2004
    Messages
    624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Prof, développeur amateur vaguement éclairé...
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 624
    Par défaut
    La solution :

    Tout d'abord, écrire une fonction qui renvoie la valeur True si l'onglet d'indice fourni doit être désactivé. Ça, c'est à vous de voir. Voilà par exemple une fonction qui dit que l'onglet d'index 1 est désactivé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    function  TForm1.IsDisabled(ATabIndex:Integer):Boolean;
     begin
      Result := ATabIndex = 1;
     end;
    Ensuite, il y a deux problèmes : le problème d'affichage, et le problème de désactivation.

    Pour le problème d'affichage, c'est simple : comme déjà dit, il faut positionner à true la propriété OwnerDraw du PageControl. Ensuite, écrire la procédure de dessin, associée à l'évènement OnDrawTab :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    procedure TForm1.PageControl1DrawTab(Control: TCustomTabControl;
      TabIndex: Integer; const Rect: TRect; Active: Boolean);
    var
       ARect: TRect;AText:string;AnIndex:Integer;
    begin
     AnIndex := TabIndex;
     ARect   := Rect;
     if Control is TPageControl then
     with Control as TPageControl, Canvas do
      begin
       Canvas.Brush.Color := clBtnFace;
       FillRect(ARect);
       if not(Active) then ARect.Top := ARect.Top + 4;
       if IsDisabled(AnIndex)
        then Canvas.Font.Color := clInactiveCaptionText
        else Canvas.Font.Color := Font.Color;
       AText := Pages[AnIndex].Caption;
       TextRect(ARect,AText,[tfCenter,tfSingleLine,tfVerticalCenter]);
      end;
    end;
    Deuxième problème : la désactivation. Pour ça, je vous propose d'utiliser une variable globale, ou champ de la fiche principale, qui va intercepter la page courante à chaque changement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (var) CurrentTabIndex : Integer;
    On écrit alors un gestionnaire d'évènement OnChanging pour mettre à jour cette valeur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    procedure TForm1.PageControl1Changing(Sender: TObject;
      var AllowChange: Boolean);
    begin
     if Sender is TPageControl then with Sender as TPageControl do
        CurrentTabIndex := TabIndex;
    end;
    Enfin, quand il y a changement, on restaure la valeur précédemment fixée si le tab voulu par l'utilisateur est désactivé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    procedure TForm1.PageControl1Change(Sender: TObject);
    begin
     if Sender is TPageControl then with Sender as TPageControl do
        if IsDisabled(TabIndex) then TabIndex := CurrentTabIndex;
    end;
    Je pense que ça correspond parfaitement à ce que vous vouliez. Mais on ne m'ôtera pas d l'idée que c'est de l'IHM zarbi, ça !

    Edit : petite précision... les thèmes de XP ne sont pas correctement gérés, pour ne pas parler de Vista. La, à mon avis, c'est un travail bien plus difficile. On peut sans doute trouver des composants personnalisés compatibles thèmes qui permettent de changer la police pour chaque onglet ?

  19. #19
    Membre éprouvé Avatar de defluc
    Homme Profil pro
    Architecte
    Inscrit en
    Mai 2002
    Messages
    1 383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    Localisation : Belgique

    Informations professionnelles :
    Activité : Architecte

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 383
    Par défaut
    Bon je vais essayer cela quand j'aurai une minute.
    Mais qu'entendez-vous par
    on ne m'ôtera pas d l'idée que c'est de l'IHM zarbi, ça !

  20. #20
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 498
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 498
    Par défaut
    salut


    il est preferable de ne pas changer si la condition voulu n'est pas corecte

    voila pour le changement d'onglet

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Type
      TAckPC = class(TbageControl)
     
    procedure TForm1.PageControl1Changing(Sender: TObject;
      var AllowChange: Boolean);
    var
      P : TPageControl;
    begin
      if Sender is TPageControl then 
      begin
        P := sender as TPageControl;
        if TAckPC(P).CanShowTab(P.TabIndex) Then
           AllowChange := FALSE;
      end;
    end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    procedure TForm1.PageControl1DrawTab(Control: TCustomTabControl;
      TabIndex: Integer; const Rect: TRect; Active: Boolean);
    var
      OutRect: TRect;AText:string;
    begin
      p :=   Control as TPageControl ;
      TabText := TAckPC(P).Tabs[TabIndex];
      OutRect := Rect;
      InflateRect (OutRect, -3, -3);
      OutRect.Left := OutRect.Left + 3;
      if Active Then
      begin
         P.Canvas.Font.Color := clred ;
      end
      else
      begin
        if  TAckPC(P).CanShowTab(TabIndex)  Then
            P.Canvas.Font.Color := clGrayText	
        else
           P.Canvas.Font.Color := clBlack;
     end;
     DrawText (Control.Canvas.Handle,
        PChar (ExtractFileName (TabText)),
        Length (ExtractFileName (TabText)),
        OutRect, dt_Left or dt_SingleLine or dt_VCenter);end;
    voila je pense que cela suffit pour gerer les onglets

    @+ Phil

Discussions similaires

  1. d'access cacher ou rendre visible onglet excel
    Par likinter dans le forum VBA Access
    Réponses: 1
    Dernier message: 02/10/2008, 16h37
  2. [E-07] Rendre un onglet visible ou non dans le ruban
    Par zit_zit dans le forum Macros et VBA Excel
    Réponses: 13
    Dernier message: 29/09/2008, 20h00
  3. Réponses: 4
    Dernier message: 20/07/2007, 17h08
  4. [VB.NET]Comment rendre les menus inaccessible?
    Par Pedro Varela dans le forum Windows Forms
    Réponses: 7
    Dernier message: 19/10/2006, 14h22
  5. Rendre un onglet inactif sur un TPAGECONTROL
    Par richard038 dans le forum Composants VCL
    Réponses: 6
    Dernier message: 12/09/2005, 10h58

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo