I need to paste some rtf text from a datagrid into a flow document. I want to paste it at the caret position in the richtextbox. This works except when i have a bullet or Numbered list. It will paste it before the bullet or number.
I have searched every where for this with no luck.
private void dgStandardText_MouseDoubleClick(object sender, MouseButtonEventArgs e) {
if (dgStandardText.SelectedItems.Count > 0) {
foreach(DataRowView row in dgStandardText.SelectedItems) {
byte[] byteArray = Encoding.ASCII.GetBytes(row[3].ToString());
using(MemoryStream ms = new MemoryStream(byteArray)) {
TextRange tr = new TextRange(txtAreaText.CaretPosition, txtAreaText.CaretPosition);
tr.Load(ms, DataFormats.Rtf);
}
}
}
NeedSave = true;
dgStandardText.SelectedItems.Clear();
}
This seems to happen when the content you're pasting includes block elements, as opposed to inline elements. For plain text, WPF seems to treat newlines (e.g., \r\n
) as paragraph breaks, so multi-line content would be translated into multiple blocks. What you want to do is insert just the inline content from each of those source blocks, such that it goes into the current block of the target document (in this case, a list item). Do this for the first source block, then insert a paragraph break, update the caret position, and move on to the next block.
Is the content of the grid row actually RTF content, or is it plain text? If it's plain text, then this should be pretty straightforward. Try changing your foreach
loop body to something like this:
var text = row[3].ToString();
var lines = text.Split(
new[] { '\r', '\n' },
StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{
var p = txtAreaText.CaretPosition;
txtAreaText.BeginChange();
p.InsertTextInRun(line);
p = p.InsertParagraphBreak();
txtAreaText.EndChange();
txtAreaText.CaretPosition = p;
}
Now, if the source content really is RTF, then things will get more complicated. I suspect you'll need to load it into an in-memory flow document and walk through the elements to figure out where the paragraph breaks are. For each paragraph, locate the inline contents that intersect the selection range, and insert them into the target document. Insert a paragraph break when you reach the end of each paragraph in the source range, just like in the example above.
I'm afraid the Documents
API is the one area of WPF that I haven't explored very thoroughly, so I can only give you a general idea of what to do. Perhaps someone else can provide more detail.