我有一个带有RichTextBox的Windows窗体。 RichTextBox的内容将写入数据库字段,该字段仅限于64k数据。 为了我的目的,这是足够的文本存储。
我已设置MaxLength属性以避免插入比允许的数据更多的数据。
rtcControl.MaxLength = 65536
但是,这仅限制允许放入文本的字符数量。 但是由于Rtf的格式化开销,我可以输入比我应该允许的文本更多的文本。如果我插入一个大图像,它甚至会变得更糟,它不会增加TextLength,但Rtf长度会增长很多。
目前,我在FormClosing事件中检查richttextboxes的Rtf属性的长度,并向用户显示一条消息,如果它是大的话。 然而,这只是一种解决方法,因为我想禁止将更多数据放入控件中(例如,如果超过MaxLength属性,则在文本框中没有任何内容插入到控件中,您会听到默认的哔声()。
任何想法如何实现这个?
我已经尝试过:
使用自定义控件扩展richtextbox并遮蔽Rtf属性以拦截插入。但是如果我添加文字似乎没有执行。
如果输入smth,即使TextChanged事件也不会触发。在控制中。
答案 0 :(得分: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的内容,如果有人试图超过该长度,请将数据恢复到以前的状态。我承认这有点hacky但似乎有效。像这样:
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);
}
}
这看起来效果很好。可能有更优雅的解决方案。
答案 1 :(得分:0)
回应其意见:
这是有效的,除了TextChanged事件似乎不会在我的环境中触发(不知道为什么)。但是因为我有自己的usercontrol,它是从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);
}