我需要使用 RichTextBox,而不是普通的文本框,因为它保持插入符号位置的方式,逐行。但是即使粘贴了文本,我也需要始终使用相同的字体。
目前我让它选择整个文本并将字体更改为原始字体(Lucida Console),但是当你粘贴它时它看起来很糟糕,因为它闪烁蓝色。
我需要使用 RichTextBox,而不是普通的文本框,因为它保持插入符号位置的方式,逐行。但是即使粘贴了文本,我也需要始终使用相同的字体。
目前我让它选择整个文本并将字体更改为原始字体(Lucida Console),但是当你粘贴它时它看起来很糟糕,因为它闪烁蓝色。
如果您以编程方式处理粘贴,请不要使用Paste方法。而是使用 Clipboard.GetDataObject().GetData(DataFormats.Text) 来获取字符串中的文本,然后使用 Rtf 或 Text 属性将文本添加到 RichTextBox:
string s = (string)Clipboard.GetDataObject().GetData(DataFormats.Text);
richTextBox.Text += s;
否则你可以处理Ctrl+V按键:
void RichTextBox1_KeyDown(object sender, KeyEventArgs e)
{
if(e.Control == true && e.KeyCode == Keys.V)
{
string s = (string)Clipboard.GetDataObject().GetData(DataFormats.Text);
richTextBox.Text += s;
e.Handled = true; // disable Ctrl+V
}
}
Darin 的方法忽略插入符号的位置并始终附加到文本的末尾。
其实还有更好的方法。使用 RichTextBox.Paste() 的重载:
DataFormats.Format plaintext_format = DataFormats.GetFormat(DataFormats.Text);
this.Paste(plaintext_format);
对我来说就像魅力一样。
@Darin 和 @idn 的答案都很好,但是在粘贴以下富文本时我都无法工作:
This is text after an arrow.
This is a new line
字体将始终更改为 WingDings。我从 MS Word 复制了这个:
具体来说,上面@idn 描述的纯文本格式方法确实只是粘贴了纯文本,但是发生了一些事情,其中字体也发生了变化。
以下代码处理 KeyUp 事件以仅选择所有文本并替换其原始颜色和字体(即格式)。为了确保这在屏幕上不会以闪烁的形式出现,采用了一种特殊的方法来禁用窗口重绘事件。控件绘制禁用发生在KeyDown事件中,RichTextBox控件自己处理粘贴事件,最后重新启用控件绘制。最后,这只发生在 CTL+V 和 SHIFT+INS 上,它们都是标准的粘贴命令:
/// <summary>
/// An application sends the WM_SETREDRAW message to a window to allow changes in that
/// window to be redrawn or to prevent changes in that window from being redrawn.
/// </summary>
private const int WM_SETREDRAW = 11;
private void txtRichTextBox_KeyDown(object sender, KeyEventArgs e)
{
// For supported Paste key shortcut combinations, suspend painting
// of control in preparation for RTF formatting updates on KeyUp
if ((e.Control && !e.Shift && !e.Alt && e.KeyCode == Keys.V) || // CTL+V
(!e.Control && e.Shift && !e.Alt && e.KeyCode == Keys.Insert)) // SHIFT+INS
{
// Send Suspend Redraw message to avoid flicker. Drawing is
// restored in txtRichTextBox_KeyUp event handler
// [this.SuspendLayout() doesn't work properly]
Message msgSuspendUpdate = Message.Create(
txtRichTextBox.Handle, WM_SETREDRAW, IntPtr.Zero, IntPtr.Zero);
NativeWindow window = NativeWindow.FromHandle(txtRichTextBox.Handle);
window.DefWndProc(ref msgSuspendUpdate);
}
}
private void txtRichTextBox_KeyUp(object sender, KeyEventArgs e)
{
// Following supported Paste key shortcut combinations, restore
// original formatting, then resume painting of control.
if ((e.Control && !e.Shift && !e.Alt && e.KeyCode == Keys.V) || // CTL+V
(!e.Control && e.Shift && !e.Alt && e.KeyCode == Keys.Insert)) // SHIFT+INS
{
// Layout already suspended during KeyDown event
// Capture cursor position. Cursor will later be placed
// after inserted text
int selStart = txtRichTextBox.SelectionStart;
int selLen = txtRichTextBox.SelectionLength;
// Replace all text with original font & colours
txtRichTextBox.SelectAll();
txtRichTextBox.SelectionFont = txtRichTextBox.Font;
txtRichTextBox.SelectionColor = txtRichTextBox.ForeColor;
txtRichTextBox.SelectionBackColor = txtRichTextBox.BackColor;
// Restore original selection
txtRichTextBox.SelectionStart = selStart;
txtRichTextBox.SelectionLength = selLen;
txtRichTextBox.ScrollToCaret();
// Resume painting of control
IntPtr wparam = new IntPtr(1); // Create a C "true" boolean as an IntPtr
Message msgResumeUpdate = Message.Create(
txtRichTextBox.Handle, WM_SETREDRAW, wparam, IntPtr.Zero);
NativeWindow window = NativeWindow.FromHandle(txtRichTextBox.Handle);
window.DefWndProc(ref msgResumeUpdate);
txtRichTextBox.Invalidate();
txtRichTextBox.Refresh();
}
}
这种方法的一个警告是,因为事件没有被抑制 ( e.Handled = true;
),所以支持标准 CTL+Z(撤消)操作。但是,此过程也会通过撤消格式更改来循环。我不认为这是一个大问题,因为下次粘贴该文本时,格式将再次被删除。
这种方法并不完美,因为如果从 RichTextBox 复制并粘贴文本(到另一个应用程序),新应用的格式仍然存在,但在我看来,这比失去撤消功能要好。如果撤消功能不重要,则将文本选择和格式化应用程序替换为文本以删除所有格式,根据此答案:https ://stackoverflow.com/a/1557270/3063884
var t = txtRichTextBox.Text;
txtRichTextBox.Text = t;