问题
I am using Rich Text object in my C# application. The only issue I am having is that when user pastes formated text from another app, it remains formated which I cannot have. Is there any way how to paste only string and ignore formatting? Thanks!
回答1:
Assuming WinForms : try this : define a RichTextBox with a KeyDown event handler like this :
Append-only example :
private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.V)
{
richTextBox1.Text += (string)Clipboard.GetData("Text");
e.Handled = true;
}
}
[Edit]
Add Clipboard RTF to RichTextBox at current insertion point (selection start) example :
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;
}
}
[End Edit]
Note 0 : The pasted in text is going to assume the current style settings in effect for the RichTextBox : if you have 'ForeGround color set to 'Blue : the pasted in text is going to be in blue.
Note 1 : This is something I knocked together quickly, and tested only a few times by creating some multi-colored and weirdly formatted RTF for the clipboard using WordPad : then pasting into into the RichTextBox1 at run-time : it did strip away all the color, indenting, etc.
Since it's not fully tested, use caution.
Note 2 : This will not handle the case of 'Insert or 'Paste via Context Menu, obviously.
Welcome all critiques of this answer, and will immediately take it down if it's not "on the mark."
回答2:
Add a handler to the KeyDown
-event to intercept the standard paste and manually insert only the plain text:
private void rtb_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.V)
{
((RichTextBox)sender).Paste(DataFormats.GetFormat("Text"));
e.Handled = true;
}
}
回答3:
I was searching for a plaintext-only richtextbox
but haven't found the solution online.
Why Plaintext-only RichTextBox
instead of a TextBox
? For example because RichTextBox
has usable undo/redo functionality and much more.
Finally I found a perfect solution by digging into the C header files of the richedit control: A RichTextBox
can be switched into plaintext mode, after that it doesn't accept formatted text and images and similar things from the clipboard and behaves like a normal TextBox
formattingwise. Fancy things like images can not be pasted and it pastes formatted text by removing the formatting.
class PlainRichTextBox : RichTextBox
{
const int WM_USER = 0x400;
const int EM_SETTEXTMODE = WM_USER + 89;
const int EM_GETTEXTMODE = WM_USER + 90;
// EM_SETTEXTMODE/EM_GETTEXTMODE flags
const int TM_PLAINTEXT = 1;
const int TM_RICHTEXT = 2; // Default behavior
const int TM_SINGLELEVELUNDO = 4;
const int TM_MULTILEVELUNDO = 8; // Default behavior
const int TM_SINGLECODEPAGE = 16;
const int TM_MULTICODEPAGE = 32; // Default behavior
[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);
bool m_PlainTextMode;
// If this property doesn't work for you from the designer for some reason
// (for example framework version...) then set this property from outside
// the designer then uncomment the Browsable and DesignerSerializationVisibility
// attributes and set the Property from your component initializer code
// that runs after the designer's code.
[DefaultValue(false)]
//[Browsable(false)]
//[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool PlainTextMode
{
get
{
return m_PlainTextMode;
}
set
{
m_PlainTextMode = value;
if (IsHandleCreated)
{
IntPtr mode = value ? (IntPtr)TM_PLAINTEXT : (IntPtr)TM_RICHTEXT;
SendMessage(Handle, EM_SETTEXTMODE, mode, IntPtr.Zero);
}
}
}
protected override void OnHandleCreated(EventArgs e)
{
// For some reason it worked for me only if I manipulated the created
// handle before calling the base method.
PlainTextMode = m_PlainTextMode;
base.OnHandleCreated(e);
}
}
回答4:
The answer from pasztorpisti worked like a charm for me. Since I'm using vb.net I thought I'd post my translated code for others:
Imports System.Runtime.InteropServices
Imports System.ComponentModel
Public Class MyRichTextBox
Inherits Windows.Forms.RichTextBox
Public Const WM_USER As Integer = &H400
Public Const EM_SETTEXTMODE As Integer = WM_USER + 89
Public Const EM_GETTEXTMODE As Integer = WM_USER + 90
'EM_SETTEXTMODE/EM_GETTEXTMODE flags
Public Const TM_PLAINTEXT As Integer = 1
Public Const TM_RICHTEXT As Integer = 2 ' Default behavior
Public Const TM_SINGLELEVELUNDO As Integer = 4
Public Const TM_MULTILEVELUNDO As Integer = 8 ' Default behavior
Public Const TM_SINGLECODEPAGE As Integer = 16
Public Const TM_MULTICODEPAGE As Integer = 32 ' Default behavior
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
End Function
Private _plainTextMode As Boolean = False
<DefaultValue(False),
Browsable(True)>
Public Property PlainTextMode As Boolean
Get
Return _plainTextMode
End Get
Set(value As Boolean)
_plainTextMode = value
If (Me.IsHandleCreated) Then
Dim mode As IntPtr = If(value, TM_PLAINTEXT, TM_RICHTEXT)
SendMessage(Handle, EM_SETTEXTMODE, mode, IntPtr.Zero)
End If
End Set
End Property
Protected Overrides Sub OnHandleCreated(e As EventArgs)
'For some reason it worked for me only if I manipulated the created
'handle before calling the base method.
Me.PlainTextMode = _plainTextMode
MyBase.OnHandleCreated(e)
End Sub
End Class
回答5:
Well the RichTextBox has a SelectionFont
property so you can for instance do the following:
Font courier;
courier = new Font("Courier new", 10f, FontStyle.Regular);
myRtb.SelectionFont = courier;
myRtb.Font = courier; //So the typed text is also the same font
If a text gets pasted, it will be automatically formatted.
回答6:
You can also use
private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.V)
{
richTextBox1.SelectedText = (string)Clipboard.GetData("Text");
e.Handled = true;
}
}
回答7:
I achieved this by udpating the font and colour for the whole RTB when its contents are changed. This works fine for me as the entry box does not need to deal with huge amounts of text.
public FormMain()
{
InitializeComponent();
txtRtb.TextChanged += txtRtb_TextChanged;
}
void txtRtb_TextChanged(object sender, EventArgs e)
{
RichTextBox rtb = (RichTextBox)sender;
rtb.SelectAll();
rtb.SelectionFont = rtb.Font;
rtb.SelectionColor = System.Drawing.SystemColors.WindowText;
rtb.Select(rtb.TextLength,0);
}
回答8:
My solution
private void OnCommandExecuting(object sender, Telerik.Windows.Documents.RichTextBoxCommands.CommandExecutingEventArgs e)
{
if (e.Command is PasteCommand)
{
//override paste when clipboard comes from out of RichTextBox (plain text)
var documentFromClipboard = ClipboardEx.GetDocumentFromClipboard("RadDocumentGUID");
if (documentFromClipboard == null)
{
(sender as RichTextBox).Insert(Clipboard.GetText());
e.Cancel = true;
}
}
}
回答9:
There is a very simple way to do this that is working well for me:
private bool updatingText;
public MyForm() {
InitializeComponent();
inputTextBox.TextChanged += inputTextBox_TextChanged;
}
private void inputTextBox_TextChanged(object sender, EventArgs e)
{
if (updatingText)
{
return;
}
updatingText = true;
try
{
var i = inputTextBox.SelectionStart;
var text = inputTextBox.Text;
inputTextBox.Rtf = "";
inputTextBox.Text = text;
inputTextBox.SelectionStart = i;
}
catch (Exception){}
updatingText = false;
}
Since the Text
property is inherently without formatting resetting the RTF text then setting the text property to the raw input removes any of the special items that may have been pasted in.
回答10:
Simple, but everything in the clipboard is in plain text when application is open.
private void timer2_Tick(object sender, EventArgs e)
{
string paste = Clipboard.GetText();
Clipboard.SetText(paste);
}
来源:https://stackoverflow.com/questions/2037827/c-sharp-rtb-paste-plain-text-without-colours-fonts