c # RTB - вставить обычный текст без цветов / шрифтов? - PullRequest
5 голосов
/ 10 января 2010

Я использую объект Rich Text в своем приложении C #. Единственная проблема, с которой я сталкиваюсь, заключается в том, что когда пользователь вставляет форматированный текст из другого приложения, он остается форматированным, чего у меня не может быть. Есть ли способ как вставить только строку и игнорировать форматирование? Спасибо!

Ответы [ 9 ]

28 голосов
/ 23 января 2010

Добавьте обработчик к событию KeyDown, чтобы перехватить стандартную вставку и вручную вставить только простой текст:

private void rtb_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Control && e.KeyCode == Keys.V)
    {
        ((RichTextBox)sender).Paste(DataFormats.GetFormat("Text"));
            e.Handled = true;
    }
}
9 голосов
/ 10 января 2010

Предполагается, что WinForms: попробуйте это: определите RichTextBox с обработчиком событий KeyDown следующим образом:

Пример только для добавления:

    private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.Control && e.KeyCode == Keys.V) 
        {
            richTextBox1.Text += (string)Clipboard.GetData("Text"); 
            e.Handled = true; 
        }
    }

[Редактировать]

Добавление буфера обмена RTF в RichTextBox в текущей точке вставки (начало выбора), например:

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

[Конец редактирования]

Примечание 0: вставленный в текст означает , что предполагает использование текущих настроек стиля для RichTextBox: если для цвета ForeGround установлено значение «Синий»: вставленный текст будет находиться в синий.

Примечание 1: Это то, что я быстро собрал вместе, и протестировал только несколько раз, создав несколько разноцветных и странно отформатированных RTF для буфера обмена с помощью WordPad: затем вставил в RichTextBox1 во время выполнения: он удалил все цвета, отступы и т. д.

Поскольку он не полностью протестирован, соблюдайте осторожность.

Примечание 2: Очевидно, что это не относится к случаю «Вставить» или «Вставить через контекстное меню».

Приветствую всех критиков этого ответа, и немедленно снимет его, если он не "на отметке".

4 голосов
/ 03 декабря 2013

Я искал обычный текст richtextbox, но не нашел решения в Интернете.

Почему только текстовый RichTextBox вместо TextBox? Например, потому что RichTextBox имеет полезные функции отмены / повтора и многое другое.

Наконец-то я нашел идеальное решение, покопавшись в заголовочных файлах C элемента управления richedit: A RichTextBox можно переключить в режим открытого текста, после чего он не принимает форматированный текст, изображения и подобные вещи из буфера обмена ведет себя как обычный TextBox форматирования. Необычные вещи, такие как изображения, не могут быть вставлены, и он вставляет форматированный текст, удаляя форматирование.

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);
    }
}
1 голос
/ 10 сентября 2015

Ответ от pasztorpisti сработал как очарование для меня. Поскольку я использую vb.net, я решил опубликовать свой переведенный код для других:

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 голосов
/ 26 марта 2019

Мое решение

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 голосов
/ 26 мая 2015

Я добился этого, обновив шрифт и цвет всего RTB, когда его содержимое изменилось.Это прекрасно работает для меня, так как в поле ввода не нужно работать с огромным количеством текста.

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);
}
0 голосов
/ 08 декабря 2013

Простой, но все в буфере обмена в открытом тексте, когда приложение открыто.

private void timer2_Tick(object sender, EventArgs e)
        {
            string paste = Clipboard.GetText();
            Clipboard.SetText(paste);
        }
0 голосов
/ 08 октября 2013

Вы также можете использовать

private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Control && e.KeyCode == Keys.V)
    {
        richTextBox1.SelectedText = (string)Clipboard.GetData("Text");
        e.Handled = true;
    }
}
0 голосов
/ 06 ноября 2012

Хорошо, RichTextBox имеет свойство SelectionFont, поэтому вы можете, например, сделать следующее:

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

Если текст будет вставлен, он будет автоматически отформатирован.

...