2008-10-10 9 views
6

J'ai un RichTextBox où j'ai besoin de mettre à jour la propriété Text fréquemment, mais quand je le fais, le RichTextBox "clignote" agaçant pendant qu'il rafraîchit tout au long d'un appel de méthode. J'espérais trouver un moyen facile de supprimer temporairement l'actualisation de l'écran jusqu'à ce que ma méthode soit terminée, mais la seule chose que j'ai trouvée sur le web est de surcharger la méthode WndProc. J'ai utilisé cette approche, mais avec quelques difficultés et effets secondaires, et cela rend le débogage plus difficile aussi. Il semble juste qu'il y ait une meilleure façon de faire cela. Quelqu'un peut-il me diriger vers une meilleure solution?Comment empêcher un RichTextBox d'actualiser son affichage?

Répondre

-3

Essayez ceci:

myRichTextBox.SuspendLayout(); 
DoStuff(); 
myRichTextBox.ResumeLayout(); 
+0

vous pouvez également ajouter myRichTextBox.Enabled = false; et le plus tard Enabled = true; – Geoff

+4

SuspendLayout() n'aide pas vraiment ici. –

0

Pourriez-vous simplement stocker le texte dans une chaîne, faites vos manipulations sur la chaîne, et à la fin de la méthode, la stocker de nouveau dans la propriété Text?

3

trouvés ici: http://bytes.com/forum/thread276845.html

Je fini par envoyer un WM_SETREDRAW via SendMessage pour désactiver puis réactivez suivi d'un Invalidate() après avoir terminé la mise à jour. Cela a semblé fonctionner.

Je n'ai jamais essayé cette méthode. J'ai écrit une application avec un RTB qui a mise en évidence de la syntaxe et utilisé ce qui suit dans la classe RTB:

protected override void WndProc(ref Message m) 
{ 
    if (m.Msg == paint) 
    { 
     if (!highlighting) 
     { 
      base.WndProc(ref m); // if we decided to paint this control, just call the RichTextBox WndProc 
     } 
     else 
     { 
      m.Result = IntPtr.Zero; // not painting, must set this to IntPtr.Zero if not painting otherwise serious problems. 
     } 
    } 
    else 
    { 
     base.WndProc(ref m); // message other than paint, just do what you normally do. 
    } 
} 

Hope this helps.

+0

WM_SETREDRAW a travaillé pour moi. Devrait être le même que LockWindowUpdate. –

-1

Je suggérerais regardant LockWindowUpdate

 

[DllImport("user32.dll", EntryPoint="LockWindowUpdate", SetLastError=true, 
ExactSpelling=true, CharSet=CharSet.Auto, 
CallingConvention=CallingConvention.StdCall)] 
+3

-1. Ce n'est pas son usage approprié. Voir http://blogs.msdn.com/b/oldnewthing/archive/2007/02/19/1716211.aspx. –

9

j'ai posé la question initiale, et la réponse qui fonctionne le mieux pour moi était l'utilisation de BoltBait de SendMessage() avec WM_SETREDRAW. Il semble avoir moins d'effets secondaires que l'utilisation de la méthode WndProc, et dans mon application, il est deux fois plus rapide que LockWindowUpdate.

Dans ma classe RichTextBox étendu, Je viens d'ajouter ces deux méthodes, et je les appelle chaque fois que je dois cesser de repeindre restart pendant que je fais un peu de traitement. Si je voulais le faire à l'extérieur de la classe RichTextBox, je pense que cela fonctionnerait simplement en remplaçant « ce » avec la référence à votre instance RichTextBox.

private void StopRepaint() 
    { 
     // Stop redrawing: 
     SendMessage(this.Handle, WM_SETREDRAW, 0, IntPtr.Zero); 
     // Stop sending of events: 
     eventMask = SendMessage(this.Handle, EM_GETEVENTMASK, 0, IntPtr.Zero); 
    } 

    private void StartRepaint() 
    { 
     // turn on events 
     SendMessage(this.Handle, EM_SETEVENTMASK, 0, eventMask); 
     // turn on redrawing 
     SendMessage(this.Handle, WM_SETREDRAW, 1, IntPtr.Zero); 
     // this forces a repaint, which for some reason is necessary in some cases. 
     this.Invalidate(); 
    } 
+0

Une chance de compléter le code? Ce n'est pas presque compilable comme écrit actuellement. –

10

Voici complet et exemple de travail:

private const int WM_USER = 0x0400; 
    private const int EM_SETEVENTMASK = (WM_USER + 69); 
    private const int WM_SETREDRAW = 0x0b; 
    private IntPtr OldEventMask;  

    [DllImport("user32.dll", CharSet=CharSet.Auto)] 
    private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); 

    public void BeginUpdate() 
    { 
     SendMessage(this.Handle, WM_SETREDRAW, IntPtr.Zero, IntPtr.Zero); 
     OldEventMask = (IntPtr)SendMessage(this.Handle, EM_SETEVENTMASK, IntPtr.Zero, IntPtr.Zero); 
    }  

    public void EndUpdate() 
    { 
     SendMessage(this.Handle, WM_SETREDRAW, (IntPtr)1, IntPtr.Zero); 
     SendMessage(this.Handle, EM_SETEVENTMASK, IntPtr.Zero, OldEventMask); 
    } 
Questions connexes