可能重复:
如何防止richTextBox 在其中粘贴图像?
如果您正在使用Richtextbox
,则有几个优点,Richtextbox
例如:
我们可以在上面使用彩色字体
在区域中设置自定义字体
在上面附加文件..等
看一下图片:
这是我的问题:
我可以把它只写成文字吗?
在我的项目中,根本不需要附加文件等。我什至不想在上面附加或粘贴图像,我只想要“纯文本”Richtextbox
我怎样才能做到这一点?
可能重复:
如何防止richTextBox 在其中粘贴图像?
如果您正在使用Richtextbox
,则有几个优点,Richtextbox
例如:
我们可以在上面使用彩色字体
在区域中设置自定义字体
在上面附加文件..等
看一下图片:
这是我的问题:
我可以把它只写成文字吗?
在我的项目中,根本不需要附加文件等。我什至不想在上面附加或粘贴图像,我只想要“纯文本”Richtextbox
我怎样才能做到这一点?
由于 RichTextBox 没有图像或对象集合,因此您必须使用 RTF 格式代码。RichTextBox 的所有数据都存储为带有特殊格式代码的纯文本,这由控件通过其 RTF 属性公开。如果您想阅读或更改此代码语言,学习此代码语言是必不可少的,学习资源可在整个网络上轻松获得,例如,请参阅此概述。RichTextBox 使用比 MS Word 等几个全功能编辑器更简化的 rtf 代码,因此在操作之前将数据加载到 RTB 通常是有益的,这将删除很多冗余数据。
长话短说,我发现有必要搜索以“pict”或“object”命令开头的 rtf 组。知道组可能是嵌套的,您不能只从那里找到第一个端组字符,您必须逐个字符地解析字符串,同时保持分组计数以找到这些组的末尾。现在您有足够的信息来删除字符串的那部分。Rtf 可能包含多个图片/对象组,因此您必须这样做,直到全部删除。这是删除这些组后返回 rtf 字符串的示例函数:
private string removeRtfObjects(string rtf)
{
//removing {\pict or {\object groups
string pattern = "\\{\\\\pict|\\{\\\\object";
Match m = Regex.Match(rtf, pattern);
while (m.Success) {
int count = 1;
for (int i = m.Index + 2; i <= rtf.Length; i++) {
//start group
if (rtf(i) == '{') {
count += 1;
//end group
} else if (rtf(i) == '}') {
count -= 1;
}
//found end of pict/object group
if (count == 0) {
rtf = rtf.Remove(m.Index, i - m.Index + 1);
break; // TODO: might not be correct. Was : Exit For
}
}
m = Regex.Match(rtf, pattern);
//go again
}
return rtf;
}
什么时候应该这样做?您已经提到了粘贴,还有插入,这些可以被 KeyDown 事件捕获,您可以在其中获取剪贴板信息并相应地处理它。当您自己处理操作时设置 e.Handled=True 表示控件不应对此组合键执行任何默认处理。这也是您在不破坏用户剪贴板的情况下阻止粘贴图像的方式。例子:
private void RichTextBox1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
//aware of Paste or Insert
if (e.Control && e.KeyCode == Keys.V || e.Shift && e.KeyCode == Keys.I) {
if (Clipboard.ContainsImage || Clipboard.ContainsFileDropList) {
//some images are transferred as filedrops
e.Handled = true;
//stops here
} else if (Clipboard.ContainsData(DataFormats.Rtf)) {
RichTextBox rtbox = new RichTextBox();
//use a temp box to validate/simplify
rtbox.Rtf = Clipboard.GetData(DataFormats.Rtf);
this.RichTextBox1.SelectedRtf = this.removeRtfObjects(rtbox.Rtf);
rtbox.Dispose();
e.Handled = true;
}
}
}
Yes, it is possible.
Handle Ctrl+V in RichTextBox1_KeyDown, then check the data format in the Clipboard: if data is plain text, paste it; if data is RTF, convert it to plain text (in a buffer without changing the Clipboard content) and paste it; don't paste any other type of data.
This is a partial example just to show you how to proceed:
private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.V)
{
// suspend layout to avoid blinking
richTextBox2.SuspendLayout();
// get insertion point
int insPt = richTextBox2.SelectionStart;
// preserve text from after insertion pont to end of RTF content
string postRTFContent = richTextBox2.Text.Substring(insPt);
// remove the content after the insertion point
richTextBox2.Text = richTextBox2.Text.Substring(0, insPt);
// add the clipboard content and then the preserved postRTF content
richTextBox2.Text += (string)Clipboard.GetData("Text") + postRTFContent;
// adjust the insertion point to just after the inserted text
richTextBox2.SelectionStart = richTextBox2.TextLength - postRTFContent.Length;
// restore layout
richTextBox2.ResumeLayout();
// cancel the paste
e.Handled = true;
}
}