Как предотвратить вставку определенных видов форматирования в WPF RichTextBox - PullRequest
5 голосов
/ 19 февраля 2011

Я хочу разрешить некоторые простые команды форматирования в WPF RichTextBox, но не другие.

Я создал панель инструментов, которая позволяет пользователям применять жирный или курсив и использовать маркированные или нумерованные списки. (По сути, я хочу поддерживать только те команды форматирования, которые подходят для блога или вики.)

Проблема в том, что пользователи могут выполнять операции вырезания и вставки, которые вставляют текст с цветами переднего плана и фона, среди других видов запрещенного форматирования. Это может привести к неприятным проблемам с юзабилити, например, пользователи вставляют белый текст на белый фон.

Есть ли способ отключить эти расширенные функции форматирования? Если нет, то есть ли способ перехватить операцию вставки и удалить ненужное форматирование?

Ответы [ 2 ]

5 голосов
/ 19 февраля 2011

Вы можете перехватить операцию вставки следующим образом:

    void AddPasteHandler()
    {
        DataObject.AddPastingHandler(richTextBox, new DataObjectPastingEventHandler(OnPaste));
    }

    void OnPaste(object sender, DataObjectPastingEventArgs e)
    {
        if (!e.SourceDataObject.GetDataPresent(DataFormats.Rtf, true)) return;
        var rtf = e.SourceDataObject.GetData(DataFormats.Rtf) as string;
        // Change e.SourceDataObject to strip non-basic formatting...
    }

, и грязная часть сохраняет некоторые, но не все форматирование.Переменная rtf будет строкой в ​​формате RTF, которую вы можете использовать сторонней библиотекой для анализа, обхода дерева по DOM-подобному шаблону и создания нового RTF с использованием только текста, полужирного шрифта и курсива.Затем добавьте это обратно в e.SourceDataObject или ряд других опций (см. Документы ниже).

Вот PastingHandler документы:

Вот один из многих анализаторов RTF:

3 голосов
/ 28 октября 2012

Вот код, если вы хотите удалить все форматирование из вставленного содержимого (не то, что вы просили, но может быть кому-то полезно):

    void OnPaste(object sender, DataObjectPastingEventArgs e)
    {
        if (!e.SourceDataObject.GetDataPresent(DataFormats.Rtf, true)) return;
        var rtf = e.SourceDataObject.GetData(DataFormats.Rtf) as string;

        FlowDocument document = new FlowDocument();
        document.SetValue(FlowDocument.TextAlignmentProperty, TextAlignment.Left);

        TextRange content = new TextRange(document.ContentStart, document.ContentEnd);

        if (content.CanLoad(DataFormats.Rtf) && string.IsNullOrEmpty(rtf) == false)
        {
            // If so then load it with RTF
            byte[] valueArray = Encoding.ASCII.GetBytes(rtf);
            using (MemoryStream stream = new MemoryStream(valueArray))
            {
                content.Load(stream, DataFormats.Rtf);
            }
        }

        DataObject d = new DataObject();
        d.SetData(DataFormats.Text, content.Text.Replace(Environment.NewLine, "\n"));
        e.DataObject = d;
    }
}
...