Scroll vertical automatique dans une RichTextBox

Résolu
cs_wowo Messages postés 5 Date d'inscription mercredi 12 novembre 2003 Statut Membre Dernière intervention 9 février 2009 - 18 juil. 2007 à 15:33
cs_wowo Messages postés 5 Date d'inscription mercredi 12 novembre 2003 Statut Membre Dernière intervention 9 février 2009 - 20 juil. 2007 à 11:53
Bonjour à tous!

Pour mon premier message, j'aimerais vous poser une question qui a déjà été traitée sur le forum, mais qui ne fonctionne pas chez moi, je commence vraiment à désespérer.

Pour situer le contexte, je suis en train d'écrire un petit chat en C# (Visual Studio 2005 - Team Edition for Software Developers). 
Les messages qu'il faut afficher du coté du client se font dans une RichTextBox, ce qui se fait très bien.

Le problème est que je voudrais que la RichTextBox fasse un autoscroll vertical lorsqu'on reçoit un nouveau message.
Voici ce que j'ai fait (et qui est souvent conseillé, d'après ce que j'ai pu voir):

                    rtbMainWin.Focus();
                    rtbMainWin.SelectionStart = rtbMainWin.Text.Length;
                    rtbMainWin.SelectionLength = 0;
                    rtbMainWin.ScrollToCaret();

Vous l'aurez compris, rtbMainWin est ma RichTextBox.
Le scroll se fait bien, mis à part qu'il ne se fait que jusque l'avant dernière ligne...

Auriez-vous une petite astuce pour que ma dernière ligne soit également prise en compte?

Merci d'avance!

wowo
A voir également:

7 réponses

ctx_man Messages postés 285 Date d'inscription mardi 28 décembre 2004 Statut Membre Dernière intervention 20 janvier 2013 3
19 juil. 2007 à 09:06
Salut !
Je vien de faire un test à l'instant. Chez moi ca marche parfaitement. Je pense que ton problème vient de l'ordre du code.
Je veux dire qu'il est fort probable que tu fasse ton ScrollToCaret() avant d'insérer ta nouvelle ligne. Du coup, effectivement, il s'arrête avant.

Ce que tu peux faire pour vérifier l'ordre d'éxécution c'est d'ajouter :

Console.WriteLine("Message Recu");

dans ta fonction qui ajoute le texte.

Et

Console.WriteLine("Auto scroll");

dans celle qui fait un autoscroll.
3
ctx_man Messages postés 285 Date d'inscription mardi 28 décembre 2004 Statut Membre Dernière intervention 20 janvier 2013 3
18 juil. 2007 à 15:50
Salut !
Quand tu di l'avant dernière ligne, tu veux dire que ta derniere ligne contenant du texte reste invisible ou c'est une ligne vide qu'il te faut ?
Quoi qu'il en soit, je sais pas si ca va corriger mais :

rtbMainWin.SelectionLength = 0; //Taille de sélection à 0 avant de définir le point de sélection (la je sais pas du tout si ca change quelque chose mais c'est plus logique selon moi)
rtbMainWin.SelectionStart = rtbMainWin.Text.Length - 1; Text.Length c'est le nombre de caractères, ta sélection devrait commencer au dernier caractère, pas en dehors de ton texte.

Pour finir tu as la possibilitée d'ajouter un saut de ligne en fin de ton texte avant de changer la place de sélection.
rtbMainWin.Text += "\n";
rtbMainWin.SelectionLength = 0;
rtbMainWin.SelectionStart = rtbMainWin.Text.Length;
0
cs_wowo Messages postés 5 Date d'inscription mercredi 12 novembre 2003 Statut Membre Dernière intervention 9 février 2009
19 juil. 2007 à 00:16
Salut, et merci de ta réponse!

En fait ce qu'il se passe, c'est que je formate mon texte en rtf.  Ainsi je peux ajouter des effets de gras, couleurs, etc avec les "balises" rtf.
Le texte que j'ajoute se place bien à la suite de l'existant, donc dans mon cas, ca ajoute bien une ligne en dessous.
Le problème se situe au moment ou la scrollbar verticale est nécessaire:
- je reçois donc un message du serveur
- le client traite cette arrivée, et formate le message en rtf.  Ensuite, il l'ajoute à la fin du corps de mon message.

Dans ma richtextbox, j'ai en fait:
{rtf .......  } qui contient l'entête de mon texte rtf + les messages formatés + } pour finir mon texte rtf

Lorsque ma box est actualisée avec le nouveau message, j'ai en fait fait un petit handle sur l'event "TextChanged", et le scroll est géré dans cet event (c'est le code que j'ai placé dans mon premier message).

Concrètement, si j'ai

<... messages peu importants, ils s'affichent bien dans la box> // Les messages ci-dessous forcent l'apparition
                                                                                              // d'une scrollbar verticale car ils
                                                                                              // dépassent la hauteur de la box
toto a écrit: bonjour 
tata a écrit: salut à toi

Et bien, la dernière ligne visible grace à mon autoscroll sera "toto a écrit: bonjour".  Si je descends la barre de scroll verticale manuellement, alors ma ligne "tata a écrit: salut à toi" apparait.  C'est cette manipulation manuelle que je voudrais supprimer.

J'ai eu la même réflexion que toi pour la longueur du texte, j'ai également essayé avec Text.Length -1, mais c'est pareil.
Le saut de ligne est automatiquement ajouté au message reçu grâce à un \par, qui signifie la fin d'un paragraphe (et donc le retour à la ligne).  Ainsi, mes messages se suivent bien.

Demain, je posterai une capture d'écran, je pense que ce sera plus facile de voir quel est le problème.
Je vais également suivre ton conseil et placer la taille de la sélection avant le point de sélection, avec longueur -1.  Je te tiens au courant!

Encore merci!

wowo
0
cs_wowo Messages postés 5 Date d'inscription mercredi 12 novembre 2003 Statut Membre Dernière intervention 9 février 2009
19 juil. 2007 à 08:39
Re à tous,

donc voila, mon code d'autoscroll est donc maintenant
                    rtbMainWin.Focus();
                    rtbMainWin.SelectionLength = 0;
                    rtbMainWin.SelectionStart = (rtbMainWin.Text.Length - 1);
                    rtbMainWin.ScrollToCaret();

Ca ne change rien, la dernière ligne n'est toujours pas lisible...

voici ce que j'ai:

et voici ce que je voudrais avoir (ici je suis obligé de scroller à la main):

wowo
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_wowo Messages postés 5 Date d'inscription mercredi 12 novembre 2003 Statut Membre Dernière intervention 9 février 2009
19 juil. 2007 à 11:26
Hello!

Hmm tu viens de me mettre sur une piste intéressante là :)
Il y avait bien un petit problème avec le handle.  Je l'ai donc supprimé, et je fais appel manuellement à la fonction. 
Les choses sont donc dans l'ordre maintenant.

Par contre, je viens de remarquer, grâce à ta suggestion, que le programme passe deux fois dans la réception du message et dans l'autoscroll.
Ainsi, après le premier passage, le scroll se fait correctement, et après le deuxième passage, il ne l'est plus, et j'ai mon problème de ligne.

Ca sent le code mal placé ça :)

En tout cas un grand merci à toi pour m'avoir mis sur la piste :D

Il n'y a plus qu'à ...

Bonne continuation!

wowo
0
ctx_man Messages postés 285 Date d'inscription mardi 28 décembre 2004 Statut Membre Dernière intervention 20 janvier 2013 3
19 juil. 2007 à 12:10
Re bonjour
Content de t'avoir aider.
Pour ton histoire de double passage, ca peux venir du fait que tu ai ajouter les handlers via l'editeur de form puis une nouvelle fois manuellement. On peut mettre plein de handlers sur un events, chacun deux recevra l'event. Si tu met deux fois le meme, l'event se fait donc deux fois.

Je te conseil de ne pas coder tes events. En théorie, pour un chat, la fenetre des messages recu/envoyé, n'est pas interactive.
Tu devrai plutot gérer ton code de scroll bar directement après l'insertion du texte.

au passage, l'ajout de texte provoque TextChanged, mais la modification de texte également. Donc quand tu ajoute ta ligne, ca provoque TextChanged, puis quand tu met en gras le nom de l'expéditeur, ca re-provoque TextChanged.

Une derniere petite astuce que j'avais utilisée pour eviter ce probleme :
Dans ton handler de TextChanged, tu peux commencer par supprimer le handler, faire ton code suceptible de changer le texte, puis remettre ton handler.

private void Handler_TextChanged(object sender, EventArgs e)
{
((RichTextBox)sender).TextChanged -= new EventHandler(Handler_TextChanged);

// Du code ....
// Tout ce qui peut arrivé ici ne déclenchera plus TextChanged

((RichTextBox)sender).TextChanged += new EventHandler(Handler_TextChanged);
}
0
cs_wowo Messages postés 5 Date d'inscription mercredi 12 novembre 2003 Statut Membre Dernière intervention 9 février 2009
20 juil. 2007 à 11:53
Hello,

c'est finalement ce que j'ai fait :
- supprimer le handler sur TextChanged
- appel à ma fonction AutoScroll (anciennement mon handler) de façon manuelle, et au bon endroit, pour que ça marche mieux.

Ca fonctionne maintenant correctement.

Pour l'astuce, c'est une façon de faire, effectivement, mais je n'ai rien dans mon handler qui modifie le texte de ma box, tout se fait avant l'appel de cet handler.
La mise en forme au format rtf se fait directement à la réception du message, avant de mettre ce dernier dans la box

En gros, <strike>mon handler</strike> ma fonction de scroll se résume à:

void AutoScroll()
{
    rtbMainWin.Focus();
    rtbMainWin.SelectionLength = 0;
    rtbMainWin.SelectionStart = (rtbMainWin.Text.Length - 1);
    rtbMainWin.ScrollToCaret();
}

et elle est appelée là ou il le faut
Encore merci pour ton aide!
0
Rejoignez-nous