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

2020-05-28 10:02发布

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!

10条回答
乱世女痞
2楼-- · 2020-05-28 10:53

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."

查看更多
够拽才男人
3楼-- · 2020-05-28 10:57

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楼-- · 2020-05-28 10:58

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.

查看更多
Bombasti
5楼-- · 2020-05-28 11:03

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;
    }
}
查看更多
登录 后发表回答