2010-04-15 7 views
0

J'ai un Windows Form avec un RichTextBox dessus. Le contenu de RichTextBox est écrit dans un champ de base de données limité à 64 Ko de données. Pour mon but c'est beaucoup plus que suffisamment de texte pour stocker.Windows.Forms Contrôle RichTextBox - Évitez d'insérer des données volumineuses

J'ai défini la propriété MaxLength pour éviter d'insérer plus de données que ce qui est autorisé.

rtcControl.MaxLength = 65536 

Cependant, cela limite seulement la quantité de caractères que l'on est autorisé à mettre dans le texte. Mais avec la surcharge de formatage de la Rtf je peux taper plus de texte que je devrais être autorisé à. Cela devient même pire si j'insère une grande image, ce qui n'augmente pas du tout la longueur de texte mais la longueur Rtf augmente beaucoup.

Pour le moment, je vérifie la longueur de la propriété Rtf de richttextboxes dans l'événement FormClosing et affiche un message à l'utilisateur s'il est trop grand. Cependant, ce n'est qu'une solution de contournement parce que je veux interdire de mettre plus de données que le contrôle (comme dans une zone de texte si vous dépassez la propriété MaxLength rien n'est inséré dans le contrôle et que vous entendez le bip par défaut). toute idée comment aCHIVE ce

je l'ai déjà essayé:.

  • au moyen d'un contrôle personnalisé qui prolonge la richtextbox et les ombres e propriété Rtf pour intercepter le insertation Mais il semble que ce ne soit pas exécuté si je ajouter du texte

  • Même l'événement TextChanged ne se déclenche pas si je tape smth. dans le contrôle.

Répondre

1

Qu'en est-faire:

gérer l'événement TextChanged et comparer chaque fois qu'il change. Il a tiré pour la saisie de texte et le glisser-déposer de l'image.

private void richTextBox1_TextChanged(object sender, EventArgs e) 
{ 
    if (richTextBox1.Rtf.Length > richTextBox1.MaxLength) 
    { 
     // do something here - I displayed a label for 
     // my example 
     label1.Text = "Text exceeds maximum size"; 
     label1.ForeColor = Color.Red; 
    } 
    else 
    { 
     label1.Text = richTextBox1.Rtf.Length.ToString(); 
     label1.ForeColor = Color.Red; 
    } 
} 

Cela a semblé fonctionner, même si je n'ai pas passé beaucoup de temps là-dessus, certes. Je soupçonne que vous pourriez tronquer le contenu s'il dépasse la taille maximale.


Edit: Je pensais à ce un peu plus et je soupçonne que vous pourriez utiliser un StringBuilder pour stocker hors le contenu du richtextbox à chaque fois et si l'on a tenté de dépasser cette longueur, restaurer les données à la précédente Etat. J'avoue que c'est un peu hacky mais ça a l'air de marcher. Quelque chose comme ceci:

StringBuild sb = new StringBuilder(); 

private void richTextBox1_TextChanged(object sender, EventArgs e) 
{ 
    if (richTextBox1.Rtf.Length > richTextBox1.MaxLength) 
    { 
     richTextBox1.Rtf = sb.ToString(); 
    } 
    else 
    { 
     sb.Insert(0,richTextBox1.Rtf); 
    } 
} 

Cela semble fonctionner plutôt bien. Il pourrait y avoir une solution plus élégante.

+0

Je ne l'ai pas encore essayé, mais pourquoi utilisez-vous un stringbuilder dans ce cas? Est-ce que j'obtiens une meilleure performance par rapport à une corde? –

+0

@SchlaWiener - Oui, probablement la chaîne serait mieux. Au départ, je pensais utiliser le StringBuilder pour ajouter le nouveau contenu RTF, mais j'ai abandonné cette idée en faveur de l'approche plus simple de "copier tout". – itsmatt

0

En réponse à itsmatt:

Cela a fonctionné, sauf pour l'événement TextChanged qui semble ne pas tirer dans mon environnement (ne sais pas pourquoi). Mais comme j'ai mon propre contrôle utilisateur qui est interessé par RichTextBox, j'ai été capable de surcharger la méthode OnTextChanged() qui est appelée. Mais le code devient un peu plus compliqué, car si vous changez le texte dans la méthode OnTextChanged(), il est à nouveau appelé, ce qui conduit à une exception StackOverflowException. Je voulais également un bip() et la position/sélection du curseur devrait être mémorisée.

Avec ce code, il devient un peu lent avec du texte> 30000, mais c'est assez bon pour moi. Les utilisateurs ne devraient pas y stocker autant de données.

private string lastText; 
    private string lastRtf; 
    private int lastSelectionStart; 
    private int lastSelectionLength; 

    private bool skipLengthCheck; 
    protected override void OnTextChanged(EventArgs e) 
    { 
     if (Rtf.Length > MaxLength && !skipLengthCheck) 
     { 
      skipLengthCheck = true; 
      Console.WriteLine("MaxLength exceeded"); 
      System.Media.SystemSounds.Beep.Play(); 
      int start = lastSelectionStart; 
      int length = lastSelectionLength; 
      base.Text = lastText; 
      base.Rtf = lastRtf; 
      SelectionStart = start > 0 ? start - 1 : 0; 
      SelectionLength = length; 
      skipLengthCheck = false;    
     } 
     else 
     { 
      lastText = Text; 
      lastRtf = Rtf; 

      base.OnTextChanged(e); 
     } 

    } 

    protected override void OnSelectionChanged(EventArgs e) 
    { 
     lastSelectionStart = SelectionStart; 
     lastSelectionLength = SelectionLength; 

     base.OnSelectionChanged(e); 
    } 
Questions connexes