2010-04-15 59 views
0

我有一個帶有RichTextBox的Windows窗體。 RichTextBox的內容被寫入數據庫字段,該字段限制爲64k數據。 對於我來說,這是足夠的文本存儲的方式。Windows.Forms RichTextBox控件 - 避免插入大數據

我設置了MaxLength屬性以避免插入比允許的數據更多的數據。

rtcControl.MaxLength = 65536 

只是限制允許放在文本中的字符數量。 但是從Rtf的格式開銷我可以鍵入更多的文本比我應該被允許。如果我插入一個大圖像,它甚至會變得更糟,它不會增加TextLength,但是Rtf長度增長很多。

此刻,我檢查FormClosing事件中的richttextboxes的Rtf屬性的長度,並向用戶顯示一條消息,如果它很大。 但是,這只是一個解決方法,因爲我想禁止將更多的數據放入控件中(比如在文本框中,如果超過MaxLength屬性,則不會在控件中插入任何東西,並且聽到默認蜂鳴聲()。任何想法如何實現這一目標

我已經嘗試過:。用它擴展了RichTextBox的和陰影日RTF財產攔截insertation自定義控件

  • 但似乎不執行它,如果我添加文本。

  • 即使我輸入了smth,TextChanged事件也不會觸發。在控制中。

回答

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

這似乎工作,雖然我沒有花很多時間在這個,誠然。如果超過最大大小,我懷疑可以截斷內容。


編輯:我想過這個多一些,我懷疑,你可以使用一個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

我還沒有嘗試過,但爲什麼你在這種情況下使用一個stringbuilder?與字符串相比,我獲得了更好的性能嗎? – 2010-04-15 16:27:53

+0

@SchlaWiener - 是的,這個字符串可能會更好。最初我正在考慮使用StringBuilder來追加新的RTF,但放棄了這個想法,轉而採用更簡單的「複製所有」方法。 – itsmatt 2010-04-15 16:37:33

0

在應對itsmatt:

這工作,除TextChanged事件似乎並不在我的環境(不知道爲什麼)開火。但是因爲我有自己的用戶控件,它是從RichTextBox插入的,所以我可以重寫OnTextChanged()方法,它被調用。 但是代碼變得有點複雜,因爲如果你改變OnTextChanged()方法中的文本,它會被再次調用,這會導致StackOverflowException。 我也想要一個Beep(),並且應該記住光標位置/選擇。

有了這段代碼,它有點慢,文本> 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); 
    }