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

Contribuez .NET Discussion :

RichTextBox surlignage ligne courante


Sujet :

Contribuez .NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite Avatar de ppphil
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    617
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2007
    Messages : 617
    Par défaut RichTextBox surlignage ligne courante
    Bonjour,
    Après de nombreuses recherches, j'ai trouvé un moyen relativement simple pour surligner la ligne courante dans dans un RichTextBox. Je compte donc bien vous en faire profiter.
    Code C# : 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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
     
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows.Forms;
    using System.Drawing;
     
    namespace WindowsApplication5
    {
      public class TRTBPlus : RichTextBox
      {
        private bool EnableEventSelectionChanged; //évite la récursivité sans fin dans HighlightCurrentLine quand il est appelé dans TRTBPlus_SelectionChanged
        private int OldLineNr; //ancienne ligne sélectionnée pour la déselectionner
     
        public TRTBPlus()
          : base()
        {
          EnableEventSelectionChanged = true;
          SelectionChanged += new EventHandler(TRTBPlus_SelectionChanged);      
        }
     
        void TRTBPlus_SelectionChanged(object sender, EventArgs e)
        {
          HighlightCurrentLine();
        }
     
        /// <summary>
        /// Surcharge spéciale de la fonction LoadFile qui met en évidence la première ligne
        /// d'un fichier à son ouverture. Le type de texte est forcé à PlainText
        /// </summary>
        /// <param name="path">Chemin du nouveau fichier</param>
        public new void LoadFile(string path)
        {
          LoadFile(path, RichTextBoxStreamType.PlainText);
          OldLineNr = -1;
          HighlightCurrentLine();
        }
     
        private void HighlightCurrentLine()
        {
          int NoLine;
          int FirstCar;
          Color OldCol;
          int OldSelStart;
     
          if (EnableEventSelectionChanged) //pour éviter une récursivité dans TRTBPlus_SelectionChanged
          {
            FirstCar = GetFirstCharIndexOfCurrentLine();
            NoLine = GetLineFromCharIndex(FirstCar);
            if (NoLine != OldLineNr)
            {
              EnableEventSelectionChanged = false;
              OldSelStart = SelectionStart;
              OldCol = Color.FromKnownColor(KnownColor.Window);
              //déselection de l'ancienne ligne
              if (OldLineNr > -1)
              {
                SelectionStart = GetFirstCharIndexFromLine(OldLineNr);
                SelectionLength = Lines[OldLineNr].Length;
                SelectionBackColor = OldCol;
                SelectionLength = 0;
              }
              SelectionStart = FirstCar;
              SelectionLength = Lines[NoLine].Length;
              SelectionBackColor = Color.FromKnownColor(KnownColor.ActiveBorder);
              DeselectAll();
              SelectionStart = OldSelStart; //remise du curseur à son ancienne position
              OldLineNr = NoLine;
              EnableEventSelectionChanged = true;
            }
          }
        }
      }
    }
    Il faudrait encore ajouter une propriété pour pouvoir choisir la couleur de surlignage et certainement encore d'autre petites choses...

    Il va de soit que tout commentaire, amélioration ou critique de ce petit bout de code seront les bienvenus.
    En attendant, bonne journée !!!

  2. #2
    Membre émérite Avatar de ppphil
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    617
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2007
    Messages : 617
    Par défaut
    Attention,
    Il y a un gros bug dans mon code :
    GetLineFromCharIndex(FirstCar); revoie le premier caractère de la ligne courante de l'interface RichTextBox et non pas le premier caractère de la ligne de la collection Lines.
    Ce qui fait que l'on surligne la ligne courante tant que l'interface est suffisamment large pour supporter toute la ligne de la collection Line et que la fin de cette ligne ne soit pas renvoyée à la ligne suivante par faute de place dans l'interface...
    Le résultat de ce bug est que l'on obtient des surlignages bizzares et que si l'on place le curseur sur la dernière ligne, on a un dépassement de bornes de tableau.
    Ce qu'il faudrait, c'est repérer le dernier caractère affiché sur la ligne effective de l'interface avec une fonction style GetLastCharIndexOfCurrentLine();...
    et que l'on ne surligne pas tous les caractère de l'item de Lines en cours.
    Si quelqu'un à une idée.....

  3. #3
    Membre émérite Avatar de ppphil
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    617
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2007
    Messages : 617
    Par défaut
    Bon ben là, j'ai trouvé.
    Pour remplacer la fonction GetLastCharIndexOfCurrentLine(); qui n'existe pas on fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    LastCar = GetFirstCharIndexFromLine(NewLineNr + 1);
    ou NewLineNr est l'index de la ligne en cours.
    A présent, on ne travaille plus avec la collection Lines.
    De plus on stocke le start et le length de l'ancien surlignage pour pouvoir le réinitialiser à sa couleur d'origine.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    private int OldLineSelStart;
    private int OldLineSelLength;
    ...
    //dans HighlightCurrentLine
    OldLineSelStart = SelectionStart;
    OldLineSelLength = SelectionLength;
    Enfin voilà la nouvelle classe
    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
     
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows.Forms;
    using System.Drawing;
     
    namespace DncnetEdt
    {
      public class LineChangedEventArgs : EventArgs
      {
        public int NewLineNr;
        public LineChangedEventArgs(int newLineNr)
        {
          NewLineNr = newLineNr;
        }
      }
     
      public class TRTBPlus : RichTextBox
      {
        public delegate void LineChangedEventHandler(object sender, LineChangedEventArgs e);
        public event LineChangedEventHandler LineChanged;
     
        # region Propriétés privées
     
        private bool EnableHighlightCurrentLine; //évite la récursivité sans fin dans HighlightCurrentLine quand il est appelé dans TRTBPlus_SelectionChanged
        private int OldLineIndex; //permet de savoir si on a changé de ligne pour éviter les accès trop fréquents à HighlightCurrentLine
        private int OldLineSelStart;
        private int OldLineSelLength;
     
        # endregion
     
        # region Propriétés publiques
     
        # endregion
     
        # region Déclaration privéess
     
        private void TRTBPlus_LineChanged(object sender, LineChangedEventArgs e)
        {
          HighlightCurrentLine(e.NewLineNr);
        }
     
        private void TRTBPlus_MouseUp(object sender, MouseEventArgs e)
        {
          //Desactive le surlignage de la ligne en cours (qui supprime la sélection après surlignage) 
          //pour permettre la sélection de plusieurs lignes
          EnableHighlightCurrentLine = true;
        }
     
        private void TRTBPlus_MouseDown(object sender, MouseEventArgs e)
        {
          //Réactive le surlignage de la ligne en cours (desactivé dans MouseDown)
          EnableHighlightCurrentLine = false;
        }
     
        private void TRTBPlus_SelectionChanged(object sender, EventArgs e)
        {
          int NoLine;
          int FirstCar;
     
          FirstCar = GetFirstCharIndexOfCurrentLine();
          NoLine = GetLineFromCharIndex(FirstCar);
          if ((NoLine != OldLineIndex) && (LineChanged != null))
          {
            LineChanged(this, new LineChangedEventArgs(NoLine));
          }
     
          //Doit rester en fin de fonction
          OldLineIndex = NoLine;
        }
     
        private void HighlightCurrentLine(int NewLineNr)
        {
          Color OldCol;
          int OldSelStart;
          int FirstCar;
          int LastCar;
          int OldLineNr;
     
          FirstCar = GetFirstCharIndexOfCurrentLine();
          LastCar = GetFirstCharIndexFromLine(NewLineNr + 1);
          if ((LastCar == -1) && (NewLineNr + 1 >= Lines.Length))
          {
            LastCar = Text.Length;
          }
     
          if (EnableHighlightCurrentLine && (LastCar >= FirstCar))
          {
            EnableHighlightCurrentLine = false; //pour éviter une récursivité dans TRTBPlus_SelectionChanged
            OldSelStart = SelectionStart;
            //TODO prendre la couleur définie par défaut
            OldCol = Color.FromKnownColor(KnownColor.Window);
     
            //déselection de l'ancienne ligne
            SelectionStart = OldLineSelStart;
            OldLineNr = GetLineFromCharIndex(OldLineSelStart);
            //Si on n'a pas encore de ligne dans le fichier on ne traite pas (nouveau fichier)
            if (OldLineNr < Lines.Length)
            {
              SelectionLength = Lines[OldLineNr].Length;
              SelectionBackColor = OldCol;
              SelectionLength = 0;
            }
     
            SelectionStart = FirstCar;
            OldLineSelStart = SelectionStart;
            SelectionLength = LastCar - FirstCar;
            OldLineSelLength = SelectionLength;
            SelectionBackColor = Color.FromKnownColor(KnownColor.ActiveBorder);
            SelectionLength = 0;
            SelectionStart = OldSelStart; //remise du curseur à son ancienne position
            EnableHighlightCurrentLine = true;
          }
        }
     
        # endregion
     
        # region Déclaration publiques
        public TRTBPlus()
          : base()
        {
          EnableHighlightCurrentLine = true;
          SelectionChanged += new EventHandler(TRTBPlus_SelectionChanged);
          MouseDown += new MouseEventHandler(TRTBPlus_MouseDown);
          MouseUp += new MouseEventHandler(TRTBPlus_MouseUp);
          TextChanged += new EventHandler(TRTBPlus_TextChanged);
          LineChanged += new LineChangedEventHandler(TRTBPlus_LineChanged);
          KeyPress += new KeyPressEventHandler(TRTBPlus_KeyPress);
        }
     
        /// <summary>
        /// Surcharge spéciale de la fonction LoadFile qui met en évidence la première ligne
        /// d'un fichier à son ouverture. Le type de texte est forcé à PlainText
        /// </summary>
        /// <param name="path">Chemin du nouveau fichier</param>
        public new void LoadFile(string path)
        {
          LoadFile(path, RichTextBoxStreamType.PlainText);
          OldLineIndex = -1;
          HighlightCurrentLine(0);
        }
        # endregion
      }
    Maintenant, la partie surlignée n'est composée que de la ligne effective du rtb.
    Joyeux Noël !

Discussions similaires

  1. [C# 2.0]Récupérer la ligne courante dans une richtextbox
    Par nephhh dans le forum Windows Forms
    Réponses: 2
    Dernier message: 23/02/2009, 22h07
  2. [c#]Surligner la ligne courant d'un richtextBox
    Par clemsye dans le forum Windows Forms
    Réponses: 2
    Dernier message: 12/07/2006, 09h18
  3. [displaytag] Utilisation des valeurs de la ligne courante
    Par ADIDASman dans le forum Servlets/JSP
    Réponses: 1
    Dernier message: 24/11/2005, 13h43
  4. [ACCESS SQL] génération d'une valeur / ligne courante ?
    Par kikidrome dans le forum Langage SQL
    Réponses: 2
    Dernier message: 15/11/2005, 13h20
  5. Ligne courante
    Par Mephyston dans le forum C++Builder
    Réponses: 2
    Dernier message: 15/10/2003, 11h12

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