How to prevent certain kinds of formatting from getting pasted into WPF RichTextBox
I want to allow some simple formatting commands within a WPF RichTextBox but not others.
I've created a toolbar that allows users to apply bold or italics, and use bulleted or numbered lists. (Basically, I only want to support the formatting commands that would be appropriate for a blog or wiki.)
The problem is that users can perform cut and paste operations that insert text with foreground and background colors, among other kinds of disallowed formatting. This can lead to nasty usability issues like users pasting white text onto a whi开发者_JS百科te background.
Is there any way to turn these advanced formatting features off? If not, is there a way I can intercept the paste operation and strip out the formatting I don't want?
You can intercept the paste operation like this:
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...
}
and the messy part is keeping some but not all of the formatting. The rtf
variable will be a string in RTF format that you can use a third-party libary to parse, walk the tree using a DOM-like pattern, and emit new RTF with just text, bold and italics. Then cram that back into e.SourceDataObject
or a number of other options (see the docs below).
Here are PastingHandler
docs:
- DataObject.AddPastingHandler Method
Here is one of many RTF parsers:
- NRTFTree - A class library for RTF processing in C#
Here is the code if you wanted to strip all formatting from pasted content (Not what you asked, but may be usefull to someone):
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;
}
}
精彩评论