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