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

Composants FMX Delphi Discussion :

Grilles, et tri (visuel dans le titre des colonnes)


Sujet :

Composants FMX Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 638
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 638
    Billets dans le blog
    65
    Par défaut Grilles, et tri (visuel dans le titre des colonnes)
    Bonjour,

    Conscient de la critique de Gilles à propos des grilles FMX et comme j'étais sur ma lancée

    , je me suis un peu plus penché sur la question.

    L'objectif, comment modifier l'entête des colonnes de grille sans pour autant créer un style personnalisé ce qui est souvent rébarbatif.

    Donc, contrairement à ce que j'ai pu initier en 2019 https://www.developpez.net/forums/d1...omiser-grille/ , et reporter dans un billet de mon blog
    j'entame une démarche par code

    Vous ne le saviez peut-être pas, mais il est tout à fait possible :
    • de modifier la hauteur du titre ;
    • de modifier sa présentation ;
    • d'ajouter des composants à un entête de colonne.


    Partant de ce principe, je commence à obtenir des résultats
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    /// Changement de hauteur
    procedure TForm131.btnHeaderSizeClick(Sender: TObject);
    var
      Header: THeader;
    begin
      Header:= THeader(StringGrid1.FindStyleResource('header'));
      Header.Height := 40;
    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
     
    /// Changement de présentation (globale)
    procedure TForm131.StringGrid1ApplyStyleLookup(Sender: TObject);
    var
      Header: THeader;
      HeaderItem: THeaderItem;
      I: Integer;
    begin
      Header:= THeader((Sender as TStringGrid).FindStyleResource('header'));
      if Assigned(Header) then
        begin
          for I := 0 to pred(Header.Count) do
            begin
              HeaderItem:= Header.Items[I];
              HeaderItem.StyledSettings := HeaderItem.StyledSettings - [TStyledSetting.Size, TStyledSetting.FontColor];
              HeaderItem.Font.Size := 20;
              HeaderItem.FontColor:= TAlphaColors.Blue;
              HeaderItem.TextSettings.HorzAlign := TTextAlign.Center;
              HeaderItem.TextSettings.VertAlign := TTextAlign.Center;
          end;
          Header.Height := 32;
      end;
    end;
    et enfin ajout d'image (ici un tpath)
    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
    procedure TForm131.btnAddPathClick(Sender: TObject);
    var
      Header: THeader;
      HeaderItem: THeaderItem;
    begin
      Header:= THeader(StringGrid1.FindStyleResource('header'));
      if assigned(Header) then HeaderItem:= Header.Items[0];
     
      with Tpath.Create(HeaderItem) do
       begin
         Align:=TalignLayout.Right;
         Parent:=HeaderItem;
         HeaderItem.TextSettings.HorzAlign := TTextAlign.Leading;
         Data.Data:='M3 13H15V11H3M3 6V8H21V6M3 18H9V16H3V18M22.54 16.88L20.41 19L22.54 21.12'+
                    'L21.12 22.54L19 20.41L16.88 22.54L15.47 21.12L17.59 19L15.47 16.88'+
                    'L16.88 15.47L19 17.59L21.12 15.46L22.54 16.88';
         Width:=Header.Height;
         OnClick:=ClickSort;
       end;
    end;
    Nom : Capture.PNG
Affichages : 579
Taille : 10,6 Ko
    en encadré, ce que j'envisage comme présentation de la partie tri (j'ai opté pour un GridPanelLayout contenant un label pour l'ordre de tri et 3 TPath, l'événement à gérer sera le onclick du GridPanelLayout)

    Pour aller plus loin et rendre les choses plus faciles je me suis même mis en tête de créer un Helper (ma marotte du moment)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     TColumnHelpers = Class helper for TCustomGrid
      public
        procedure SetAColumnAsSortable(const Column : TColumn; const HeaderHeight : Single =0 );
        function IsColumnSortable(const Column : TColumn) : Boolean;
      end;
    Voilà (enfin) ma question, il va me falloir accéder à des propriétés (ce qu'un helper ne permet pas), évènements et fonctions spécifiques, pour ne pas avoir à modifier le composant, je songeais utiliser le tagobject de chaque colonne avant de me lancer dans cette aventure, est-ce possible ?

  2. #2
    Membre Expert
    Avatar de pprem
    Homme Profil pro
    MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Inscrit en
    Juin 2013
    Messages
    1 876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 876
    Par défaut
    Utiliser le TagObject est une solution mais normalement les propriétés "tag" sont réservées au développeur final et ne devraient pas être modifiées dans les composants.

    Là, à toi de voir si tu fermes l'accès à cette propriété pour les développeurs qui utiliseront ton code. Après tout c'est une approche qui te permet de faire tes essais sans trop te prendre la tête, donc je dirais GO.

    L'autre solution que tu peux tenter, que j'appelle généralement "l'astuce de Paul Toth" (puisque c'est de lui que je la tiens et que je n'y avais pas pensé avant), c'est de surcharger la classe en l'appelant avec le même nom pour ajouter des fonctionnalités en code sans avoir à réimporter le composant dans l'IDE (par contre ton unité contenant le code devra être chargée en dernier dans l'interface de l'unité qui utilise la grille).

    un truc du style:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    type
    TGrid = class(FRM.JeNeSaisPlusQuelleUnite.TGrid)
    end;

  3. #3
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 638
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 638
    Billets dans le blog
    65
    Par défaut
    surcharger la classe en l'appelant avec le même nom pour ajouter des fonctionnalités en code
    ce truc-là, je l'envisage aussi (je ne savais pas que Paul en avait fait un "truc"), c'est ce que j'entends aussi par dériver le composant de base.
    Je l'ai déjà fait pour je ne sais plus quel composant ni dans quelles circonstances

    tu fermes l'accès à cette propriété pour les développeurs qui utiliseront ton code.
    exact, mais qui utilise tagobject

  4. #4
    Membre Expert
    Avatar de pprem
    Homme Profil pro
    MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Inscrit en
    Juin 2013
    Messages
    1 876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 876
    Par défaut
    Citation Envoyé par SergioMaster Voir le message
    exact, mais qui utilise tagobject
    euh... moi

  5. #5
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 638
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 638
    Billets dans le blog
    65
    Par défaut
    Après avoir longtemps galéré sur le dessin (https://www.developpez.net/forums/d2...ayout-runtime/)

    J'arrive au bout de la méthode utilisée à base de Helpers et de l'utilisation d'un "simple" TagObject. De plus en plus complexe, il est évident qu'une "surclasse" du composant serait plus facile.
    Nom : Capture.PNG
Affichages : 500
Taille : 48,8 Ko

    En effet, même s'il me reste quelques petits bogues (ordre du tri, largeur du gridpanellayout), c'est surtout la question application du tri sur lequel je m'attache aujourd'hui.

    Plusieurs questions restent en suspens :
    - déclencher le tri
    - trier un tableau (stringgrid) s'il n'est pas lié à une source de données, plus exactement s'il s'agit d'un remplissage par code ou par liaisons d'objets (prototypebindsource et oncreateADapter pour les "vrais objets".
    N.B. si le tableau est lié, je n'ai envisagé qu'une liaison à une source de données Firedac permettant d'utiliser IndexFieldNames. En parlant de ceci, toujours en clin d'œil à Gilles , il serait aussi possible d'ajouter un Combobox ou un Searchbox, selon la même technique que pour le tri et d'utiliser la propriété Filter des sources de données Firedac.

    un petit retour sur le code de mon TagObject
    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
    26
    27
    28
    29
    30
    31
    32
     TGridObject = class
      private
        FGridSelectedRange: TRect;
        FGridSelectedCols: TList<Integer>;
        FGridSelectedRows: TList<Integer>;
        FGridSelColor: TAlphaColor;
        FGridSelOpacity: Single;
        FGridHeaderBrush : TBrush;
        FGridHeaderStrokeBrush : TStrokeBrush;
        FGridSelBrush : TBrush;
        FSelectionMode : TGridSelectionMode;
        FOwner: TStringGrid;
        FSortableColumns: TList<TColumn>;
        FSortedColumns: integer;
        procedure SetGridSelOpacity(const Value: Single);
        procedure SetGridSelColor(const Value: TAlphaColor);
        procedure SetSortedColumns(const Value: integer);
      public
       property GridSelColor  : TAlphaColor read FGridSelColor;
       property GridSelOpacity  : Single read FGridSelOpacity write SetGridSelOpacity;
       property GridSelectedCols : TList<Integer> read FGridSelectedCols; // write SetGridSelectedCols;
       property GridSelectedRows : TList<Integer> read FGridSelectedRows; // write SetGridSelectedRows;
       property GridSelectedRange : TRect read FGridSelectedRange;  // write SetGridSelectedRange;
       property GridSelBrush : TBrush read FGridSelBrush;
       property GridHeaderBrush : TBrush read FGridHeaderBrush;
       property GridHeaderStrokeBrush : TStrokeBrush read FGridHeaderStrokeBrush;
       property SelectionMode : TGridSelectionMode read FSelectionMode;
       property SortableColumns : TList<TColumn> read FSortableColumns;
       property SortedColumns : integer read FSortedColumns write SetSortedColumns;
       property Owner : TStringGrid read FOwner; // write Setowner;
       constructor Create(Owner : TStringGrid);
      end;
    Tout d'abord, je me heurte à l'ordre de ma liste de colonnes "triables" SortableColumns, il faudrait qu'elle soit triée en ordre ascendant en fonction du tag de l'entête de colonne (mauvais choix, je pense, j'aurai certainement dû utiliser le tag de colonne. Facile à corriger). Bon, étant donné que c'est un TList<TColumn> ce n'est qu'un peu de code de tri à écrire donc solvable.

    Le tri d'une liaison à des objets (OnCreateAdapter) puisqu'un TList<unobjet> sera utilisé, c'est encore gérable, quoi que je n'aie, jusqu'à présent, codé des tris que sur un seul critère.
    Le tri d'un tableau non lié ou d'un TPrototypeBindSource, par contre, je ne sais pas vraiment par quel bout commencer

  6. #6
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 638
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 638
    Billets dans le blog
    65
    Par défaut
    Des recherches pour une autre personnalisation des cellules m'ont fait découvrir une unité FMX.Grid.Style
    Quelqu'un a déjà utilisé et si oui comment faire ?

    J'y vois de gros élagages s'il est possible d'utiliser cette unité en exemple la propriété HeaderItem[const Index: Integer]

Discussions similaires

  1. Aligner les titres des colonnes dans un datagrid
    Par bonnet85 dans le forum VB 6 et antérieur
    Réponses: 0
    Dernier message: 02/04/2008, 16h01
  2. Probleme d'affichage dans les titres des fenetres
    Par pierrot10 dans le forum Windows XP
    Réponses: 4
    Dernier message: 24/01/2008, 09h01
  3. Affichage du titre des colonnes dans un DBGrid
    Par Debure dans le forum C++Builder
    Réponses: 6
    Dernier message: 05/10/2005, 23h41
  4. DBGrid, comment dessiner dans les titres des colonnes
    Par dleu dans le forum Bases de données
    Réponses: 9
    Dernier message: 04/11/2004, 17h49
  5. [dbGrid]Image dans le titre des colonnes d'un dbGrid
    Par dleu dans le forum Bases de données
    Réponses: 1
    Dernier message: 31/08/2004, 18h01

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