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
Sub
You 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
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
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
Function
If 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
Function
We'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 >>