If a user wants to paste in text that is formatted as a table, I would like it to just paste the data in the tables, becuase our reporting technology cannot handle html tables.
Any ideas if this can be done? I don't see anything in the Demos about special paste functions
5 Answers, 1 is accepted
RadRichTextBox does not have customization options regarding the text that is being pasted.
However, you can attach to the CommandExecuting event of the rich text box and manipulate the data from the clipboard:
this.radRichTextBox1.CommandExecuting += OnCommandExecuting;private void OnCommandExecuting(object sender, CommandExecutingEventArgs e){ if (e.Command is PasteCommand) { DocumentFragment fragment = ClipboardEx.GetDocument(); if (fragment != null) { RadDocument document = fragment.ToDocument(); foreach (Block block in document.EnumerateChildrenOfType<Block>().ToList<Block>()) { if (block is Table) { block.Parent.Children.Remove(block); } else if (block is Paragraph) { Paragraph para = (Paragraph)block; foreach (Inline item in para.Inlines) { if (item is ImageInline || item is FloatingImageBlock || item is AnnotationMarkerBase) { para.Inlines.Remove(item); } else if (item is Span) { var span = item as Span; span.ForeColor = Colors.Black; span.FontFamily = FontFamily; span.FontSize = FontSize; } } } } DocumentSelection selection = new DocumentSelection(document); selection.SelectAll(); this.radRichTextBox1.InsertFragment(new DocumentFragment(selection)); e.Cancel = true; } }}In the example code images and annotation markers (hyperlinks, comments, etc.) are removed. Table cell data is inserted while the table itself is not.
You can do some more customization depending on the logic in your case. If you need further assistance, contact us again.
Kind regards,
Martin
the Telerik team
I am starting with just a simple table that I created in excel and copied out.
I translated the code to VB for our use, is there something I messed up?
Private Sub richTextBox_CommandExecuting(sender As Object, e As Telerik.Windows.Documents.RichTextBoxCommands.CommandExecutingEventArgs) Handles richTextBox.CommandExecuting If e.Command.GetType Is GetType(Telerik.Windows.Documents.RichTextBoxCommands.PasteCommand) Then Dim fragment As DocumentFragment = ClipboardEx.GetDocument() If fragment IsNot Nothing Then Dim document As RadDocument = fragment.ToDocument() For Each chunk As Telerik.Windows.Documents.Model.Block In document.EnumerateChildrenOfType(Of Telerik.Windows.Documents.Model.Block)().ToList If chunk.GetType Is GetType(Table) Then chunk.Parent.Children.Remove(chunk) ElseIf chunk.GetType Is GetType(Paragraph) Then Dim para As Paragraph = chunk For Each item As Inline In para.Inlines If item.GetType Is GetType(ImageInline) Or item.GetType Is GetType(FloatingImageBlock) Or item.GetType Is GetType(AnnotationMarkerBase) Then para.Inlines.Remove(item) ElseIf item.GetType Is GetType(Span) Then Dim span As Span = item span.ForeColor = Colors.Black span.FontFamily = FontFamily span.FontSize = FontSize End If Next End If Next Dim selection As New DocumentSelection(document) selection.SelectAll() Me.richTextBox.InsertFragment(New DocumentFragment(selection)) e.Cancel = True End If End If End SubYou are right, the code from my previous snippet skips the tables altogether and the data in them is ignored.
You can use the following code to remove the table while adding its contents to the document:
private void editor_CommandExecuting(object sender, CommandExecutingEventArgs e){ if (e.Command is PasteCommand) { DocumentFragment fragment = ClipboardEx.GetDocument(); if (fragment != null) { RadDocument document = fragment.ToDocument(); RadDocument newDocument = new RadDocument(); foreach (Section section in document.Sections) { Section sectionCopy = section.CreateShallowCopy() as Section; foreach (Block block in section.Children) { if (block is Paragraph) { Paragraph originalParagraph = (Paragraph)block; Paragraph strippedParagraph = this.CreateFormattingStrippedCopy(originalParagraph); if (originalParagraph.IsEmpty || !strippedParagraph.IsEmpty) { sectionCopy.Blocks.Add(strippedParagraph); } } else if (block is Table) { foreach (Paragraph paragraph in this.GetParagraphsFromTable((Table)block)) { Paragraph strippedParagraph = this.CreateFormattingStrippedCopy(paragraph); if (!strippedParagraph.IsEmpty) { sectionCopy.Blocks.Add(strippedParagraph); } } } } newDocument.Sections.Add(sectionCopy); } newDocument.MeasureAndArrangeInDefaultSize(); DocumentSelection selection = new DocumentSelection(newDocument); selection.SelectAll(); this.editor.InsertFragment(new DocumentFragment(selection)); e.Cancel = true; } }}private Paragraph CreateFormattingStrippedCopy(Paragraph paragraph){ Paragraph newParagraph = paragraph.CreateShallowCopy() as Paragraph; foreach (Inline item in paragraph.Inlines) { if (item is Span) { Span spanCopy = item.CreateDeepCopy() as Span; if (spanCopy.Text != string.Empty) { //change ForeColor, FontSize and FontFamily if required spanCopy.ForeColor = Colors.Black; newParagraph.Inlines.Add(spanCopy); } } } return newParagraph;}private List<Paragraph> GetParagraphsFromTable(Table table){ List<Paragraph> paragraphs = new List<Paragraph>(); foreach (Block child in table.Children) { foreach (Block block in child.EnumerateChildrenOfType<Block>().ToList<Block>()) { if (block is Paragraph) { paragraphs.Add((Paragraph)block); } else if (block is Table) { paragraphs.Union(GetParagraphsFromTable((Table)block)); } } } return paragraphs;}Here is the equivalent code in VB:
Private Sub richTextBox_CommandExecuting(sender As System.Object, e As Telerik.Windows.Documents.RichTextBoxCommands.CommandExecutingEventArgs) If TypeOf e.Command Is PasteCommand Then Dim fragment As DocumentFragment = ClipboardEx.GetDocument() If fragment IsNot Nothing Then Dim document As RadDocument = fragment.ToDocument() Dim newDocument As New RadDocument() For Each section As Section In document.Sections Dim sectionCopy As Section = TryCast(section.CreateShallowCopy(), Section) For Each block As Block In section.Children If TypeOf block Is Paragraph Then Dim originalParagraph As Paragraph = DirectCast(block, Paragraph) Dim strippedParagraph As Paragraph = Me.CreateFormattingStrippedCopy(originalParagraph) If originalParagraph.IsEmpty OrElse Not strippedParagraph.IsEmpty Then sectionCopy.Blocks.Add(strippedParagraph) End If ElseIf TypeOf block Is Table Then For Each paragraph As Paragraph In Me.GetParagraphsFromTable(DirectCast(block, Table)) Dim strippedParagraph As Paragraph = Me.CreateFormattingStrippedCopy(paragraph) If Not strippedParagraph.IsEmpty Then sectionCopy.Blocks.Add(strippedParagraph) End If Next End If Next newDocument.Sections.Add(sectionCopy) Next newDocument.MeasureAndArrangeInDefaultSize() Dim selection As New DocumentSelection(newDocument) selection.SelectAll() Me.richTextBox.InsertFragment(New DocumentFragment(selection)) e.Cancel = True End If End IfEnd SubPrivate Function CreateFormattingStrippedCopy(paragraph As Paragraph) As Paragraph Dim newParagraph As Paragraph = TryCast(paragraph.CreateShallowCopy(), Paragraph) For Each item As Inline In paragraph.Inlines If TypeOf item Is Span Then Dim spanCopy As Span = TryCast(item.CreateDeepCopy(), Span) If spanCopy.Text <> String.Empty Then 'change ForeColor, FontSize and FontFamily if required spanCopy.ForeColor = Colors.Black newParagraph.Inlines.Add(spanCopy) End If End If Next Return newParagraphEnd FunctionPrivate Function GetParagraphsFromTable(table As Table) As List(Of Paragraph) Dim paragraphs As New List(Of Paragraph)() For Each child As Block In table.Children For Each block As Block In child.EnumerateChildrenOfType(Of Block)().ToList() If TypeOf block Is Paragraph Then paragraphs.Add(DirectCast(block, Paragraph)) ElseIf TypeOf block Is Table Then paragraphs.Union(GetParagraphsFromTable(DirectCast(block, Table))) End If Next Next Return paragraphsEnd FunctionIf you have any other questions, do not hesitate to contact us again.
Regards,
Martin
the Telerik team
Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>
Thanks, I modified your code slightly to loop through the table rows, and just create one paragraph per row instead of including a paragraph for every line. This lets the data still somewhat look like a table when pasted, instead of the data for each cell being inserted as it's own line. The only way i could find to seperate the spans from each other was to add empty spaces at the end of the text, which is fine.
Now my users can use spaces to format the table the rest of the way, but there is no table formatting included, so the report still works.
Private Sub richTextBox_CommandExecuting(sender As Object, e As Telerik.Windows.Documents.RichTextBoxCommands.CommandExecutingEventArgs) Handles richTextBox.CommandExecuting If e.Command.GetType Is GetType(Telerik.Windows.Documents.RichTextBoxCommands.PasteCommand) Then Dim fragment As DocumentFragment = ClipboardEx.GetDocument() If fragment IsNot Nothing Then Dim document As RadDocument = fragment.ToDocument() Dim newDocument As New RadDocument() For Each section As Section In document.Sections Dim sectionCopy As Section = TryCast(section.CreateShallowCopy(), Section) For Each block As Block In section.Children If TypeOf block Is Paragraph Then Dim originalParagraph As Paragraph = DirectCast(block, Paragraph) Dim strippedParagraph As Paragraph = Me.CreateFormattingStrippedCopy(originalParagraph) If originalParagraph.IsEmpty OrElse Not strippedParagraph.IsEmpty Then sectionCopy.Blocks.Add(strippedParagraph) End If ElseIf TypeOf block Is Table Then For Each row As TableRow In Me.GetRowsFromTable(DirectCast(block, Table)) Dim newPara As New Paragraph For Each item As Span In GetSpansFromRow(row) newPara.Inlines.Add(item) Next sectionCopy.Blocks.Add(newPara) Next 'For Each paragraph As Paragraph In Me.GetParagraphsFromTable(DirectCast(block, Table)) ' Dim strippedParagraph As Paragraph = Me.CreateFormattingStrippedCopy(paragraph) ' If Not strippedParagraph.IsEmpty Then ' sectionCopy.Blocks.Add(strippedParagraph) ' End If 'Next End If Next newDocument.Sections.Add(sectionCopy) Next newDocument.MeasureAndArrangeInDefaultSize() Dim selection As New DocumentSelection(newDocument) selection.SelectAll() Me.richTextBox.InsertFragment(New DocumentFragment(selection)) e.Cancel = True End If End If End Sub Private Function CreateFormattingStrippedCopy(paragraph As Paragraph) As Paragraph Dim newParagraph As Paragraph = TryCast(paragraph.CreateShallowCopy(), Paragraph) For Each item As Inline In paragraph.Inlines If TypeOf item Is Span Then Dim spanCopy As Span = TryCast(item.CreateDeepCopy(), Span) If spanCopy.Text <> String.Empty Then 'change ForeColor, FontSize and FontFamily if required 'spanCopy.ForeColor = Colors.Black newParagraph.Inlines.Add(spanCopy) End If End If Next Return newParagraph End Function Private Function GetSpansFromRow(table As TableRow) As List(Of Span) Dim spans As New List(Of Span)() For Each child As Block In table.Children For Each block As Paragraph In child.EnumerateChildrenOfType(Of Paragraph)().ToList() If TypeOf block Is Paragraph Then For Each item As Inline In block.Inlines If TypeOf item Is Span Then Dim spanCopy As Span = TryCast(item.CreateDeepCopy(), Span) If spanCopy.Text <> String.Empty Then spanCopy.Text &= " " spans.Add(spanCopy) End If End If Next End If Next Next Return spans End Function Private Function GetRowsFromTable(table As Table) As List(Of TableRow) Dim rows As New List(Of TableRow)() For Each child As Block In table.Children For Each block As Block In child.EnumerateChildrenOfType(Of Block)().ToList() If TypeOf block Is TableRow Then rows.Add(DirectCast(block, TableRow)) End If Next Next Return rows End Function Private Function GetParagraphsFromTable(table As Table) As List(Of Paragraph) Dim paragraphs As New List(Of Paragraph)() For Each child As Block In table.Children For Each block As Block In child.EnumerateChildrenOfType(Of Block)().ToList() If TypeOf block Is Paragraph Then paragraphs.Add(DirectCast(block, Paragraph)) ElseIf TypeOf block Is Table Then paragraphs.Union(GetParagraphsFromTable(DirectCast(block, Table))) End If Next Next Return paragraphs End FunctionWe're glad to hear you found your way around and made it work better for your case.
If you need anything additional, feel free to contact us again.
Regards,
Ivailo Karamanolev
the Telerik team
Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>