2010-04-15 4 views
0

У меня есть форма Windows с RichTextBox. Содержимое RichTextBox записывается в поле базы данных, которое ограничено данными 64k. Для моей цели это более чем достаточно для хранения текста.Windows.Forms RichTextBox Control - Избегайте вставки больших данных

Я установил свойство MaxLength, чтобы избежать вставки большего количества данных, чем разрешено.

rtcControl.MaxLength = 65536 

В любом случае, это ограничивает количество символов, которые разрешено помещать в текст. Но с форматированием накладных расходов из Rtf я могу напечатать больше текста, чем мне должно быть позволено. Это даже ухудшается, если я вставляю большое изображение, которое не увеличивает TextLength, но Rtf Length растет довольно много.

В настоящее время я проверяю длину свойства Rtf richttextboxes в событии FormClosing и отображаю сообщение пользователю, если оно велико. Однако это просто обходной путь, потому что я хочу запретить помещать больше данных, чем разрешено в элемент управления (например, в текстовом поле, если вы превысите свойство MaxLength, в элемент управления ничего не вводится, и вы слышите звуковой сигнал по умолчанию().

Любые идеи, как для того чтобы достигнуть этого

Я уже пробовал:?.

  • с помощью пользовательского элемента управления, который расширяет RichTextBox и тени е Rtf собственности на перехват insertation Но, кажется, это не выполняется, если I добавить текст.

  • Даже событие TextChanged не срабатывает, если я набираю smth. в контроле.

ответ

1

Что по поводу этого:

Обрабатывать событие TextChanged и сравнить каждый раз, когда она меняется. Он запускается для ввода текста и перетаскивания изображения.

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; 
    } 
} 

Это, казалось, сработало, хотя я не потратил много времени на это, по общему признанию. Я подозреваю, что вы можете обрезать содержимое, если оно превышает максимальный размер.


Edit: Я думал об этом еще немного, и я подозреваю, что вы могли бы использовать StringBuilder для хранения от содержимого в RichTextBox каждый раз, и если одна попытка превысить эту длину, восстановить данные предыдущего государство. Я признаю, что это немного хаки, но, похоже, это работает. Что-то вроде этого:

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); 
    } 
} 

Это похоже на работу очень хорошо. Возможно, будет более элегантное решение.

+0

Я еще не пробовал, но зачем вы используете строковый строитель в этом случае? Я получаю лучшую производительность по сравнению со строкой? –

+0

@SchlaWiener - Да, наверное, строка будет лучше. Первоначально я думал об использовании StringBuilder для добавления нового материала RTF, но отказался от этой идеи в пользу более простого подхода «копировать все». – itsmatt

0

В ответ на itsmatt:

Это работало, для TextChanged Событие, которое, кажется, не стрелять в моем окружении (не знаю почему), за исключением. Но так как у меня есть собственный пользовательский контроль, который переводится с RichTextBox, я смог переопределить метод OnTextChanged(), который вызывается. Но код get немного сложнее, потому что, если вы меняете текст в методе OnTextChanged(), он снова вызывается, что приводит к исключению StackOverflowException. Я также хотел получить звуковой сигнал(), и положение/выбор курсора нужно запомнить.

С этим кодом он становится медленным с текстом> 30000, но для меня это достаточно хорошо. В любом случае пользователи не должны хранить столько данных.

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); 
    } 
Смежные вопросы