mardi 1 octobre 2013

Search Text in RichTextBox - Find function

Comment rechercher du Texte dans un contrôle RichTextBox. Voici une application Windows  un peu aboutie permettant d'ouvrir un fichier en édition dans une RichTextBox, de modifier ce fichier et de le sauvegarder.

Requirements :
Visual Studio 2010 C#
.NET Framework 3.5
Contrôle : RichTextBox

Structure et spécifications de l'application

Vous avez certainement déjà joué avec des fichiers sur disque dur afin de les ouvrir, de les traiter, de les afficher. Ici on va ouvrir un fichier et faire des recherches de texte dans ce fichier.

Il y a bon nombre de choses à faire lors de l'ouverture de la modification et de la sauvegarde d'un fichier, tous ces cas seront traité par l'application qui se compose d'un TabControl principal tabControlMain et de deux TabPages, tabPageFichier qui va permettre d'ouvrir de modifier et sauver le fichier dans le contrôle RichTextBox et tabPageConsole qui va permettre d'afficher le comportement de l'application et certains messages d'erreur lors de l'utilisation de l'application :

Application RichTextBox Find - Structure
Je vais créer un composant utilisateur dérivé RichTextBox et encapsuler mon contrôle dans une DLL ceci afin de créer un contrôle utilisateur que je pourrais à la fois utiliser dans mon application principale puis réutiliser dans une autre application.

A ma solution principale nommée RichTextBoxFind j'ajoute donc une Class Librairie WindowsFormsControlLibraryRichTextBoxFind qui va contenir une boite de dialogue DialogFind et mon nouveau contrôle utilisateur dérivé d'un contrôle RichTextBox, RichTextBoxFind :

Application RichTextBox Find - Visual Studio Solution
Ma boite de dialogue créé un Event particulier auquel mon nouveau composant utilisateur RichTextBoxFind va pouvoir s'abonner afin d'être prévenu lorsque l'utilisateur cliquera sur le bouton "Chercher". DialogFind est toute simple et propose les RichTextBoxFinds Options à l'utilisateur :

RichTextBoxFinds Options 
Je veux pouvoir montrer cette boite de dialogue lorsque l'utilisateur pressera les touches "Ctrl-F" dans la RichTextBox.

Détails de l'implémentation

Dans la DLL WindowsFormsControlLibraryRichTextBoxFind de ma RichTextBoxFind Windows Application, je créé un composant utilisateur que je nomme RichTextBoxFind :

Contrôle ou Composant Utilisateur RichTextBoxFind
Je dérive mon contrôle d'un contrôle RichTextBox de base :
public partial class RichTextBoxFind : RichTextBox // Component,

Dans ce contrôle, je créé un KeyEventHandler : RichTextBoxFind_KeyUp :
private void RichTextBoxFind_KeyUp( object sender, System.Windows.Forms.KeyEventArgs e )
{
// If key pressed in RichTextBox is "Ctrl+F" then Find
if ( e.Modifiers == Keys.Control & e.KeyCode == Keys.F )
{
if (findDialog == null)
{
findDialog = new DialogFind();
findDialog.Finded += new FindEventHandler(OnDialogFind);
}
this.HideSelection = false;

// Recuperer le texte sélectionné dans le RTB
string sel = this.SelectedText;
if ( sel != string.Empty )
{
TextBox tb = ( TextBox )GetControl( findDialog, "textBoxFind" );
tb.Text = sel.Trim();
}
findDialog.ShowDialog();
}
}

Qui s'occupe de capter les touches pressées par l'utilisateur et récupère le "Ctrl-F" pour afficher la boite de dialogue DialogFind et au passage on abonne la fonction OnDialogFind à l'événement Finded. 
L'algorithme de recherche de texte dans un RichTextBox se trouve dans la fonction OnDialogFind de ce nouveau composant utilisateur.

Ma boite de dialogue DialogFind créé un User Event Handler : Finded :
namespace WindowsFormsControlLibraryRichTextBoxFind
{
    // A delegate type for hooking find notifications.
    public delegate void FindEventHandler( string findWhat, RichTextBoxFinds findOption );
    
    public partial class DialogFind : Form
    {
        public event FindEventHandler Finded;
        ...

Qui va permettre de déclencher un événement Finded à destination de mon contrôle RichTextBoxFind lorsque l'utilisateur cliquera sur le bouton "Chercher".

Ma boite de dialogue possède ainsi un EventHandler qui s'occupe de gérer les options de recherche et de déclencher l'événement Find à destination de la RichTextBox :
private void buttonFind_Click( object sender, EventArgs e )
{
if ( textBoxFind.TextLength > 0 )
{
RichTextBoxFinds findOption = new RichTextBoxFinds();
if ( checkBoxMatchCase.Checked ) 
findOption = RichTextBoxFinds.MatchCase;
if ( checkBoxWholeWord.Checked ) 
findOption = findOption | RichTextBoxFinds.WholeWord;
if ( radioButtonUp.Checked ) 
findOption = findOption | RichTextBoxFinds.Reverse;
if ( Finded != null )
{
this.Finded( textBoxFind.Text, findOption );
}
}
}

Pour utiliser mon nouveau composant utilisateur dans mon application principale. J'utilise une possibilité de la ToolBox bouton droit -> "Choose Items" :

ToolBox de Visual Studio Ajouter un composant utilisateur
Qui me permet de browser ma DLL WindowsFormsControlLibraryRichTextBoxFind.dll et ainsi d'ajouter dans la ToolBox mon nouveau composant :

ToolBox Nouveau composant RichTextBoxFind
En drag and dropant ce nouveau contrôle dans la fenêtre de mon application je peux l'utiliser :

RichTextBoxFind - Fenêtre principale
L'application principale s'occupe de jouer avec le fichier de l'afficher et lorsque je presse les touches "Ctrl-F" de mon application en ayant au préalable sélectionné le texte que je souhaite rechercher voici l'exécution :


RichTextBoxFind - Windows Application - Exécution

Download Source Code

Ce code source en C# fait bien d'autres choses qui ne sont pas détaillées ici concernant le traitement des fichiers ... à vous de creuser. Tout l'intérêt de cet exemple réside dans l'utilisation de la fonction Find() du RichTextBox au sein de l'algorithme OnDialogFind car j'ai trouvé sur internet d'autres exemples bien plus hasardeux.


Aucun commentaire:

Enregistrer un commentaire