c# RTB - paste plain text without colours/fonts?

前端 未结 10 1197
感动是毒
感动是毒 2021-02-06 07:42

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

相关标签:
10条回答
  • 2021-02-06 08:07

    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
    
    0 讨论(0)
  • 2021-02-06 08:07

    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;
            }
        }
    }
    
    0 讨论(0)
  • 2021-02-06 08:12

    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);
        }
    }
    
    0 讨论(0)
  • 2021-02-06 08:12

    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.

    0 讨论(0)
  • 2021-02-06 08:17

    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.

    0 讨论(0)
  • 2021-02-06 08:18

    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);
            }
    
    0 讨论(0)
提交回复
热议问题