Styles with names only different in spaces are treated as one.
Workaround:
var rtf = File.ReadAllText(fileName);
rtf = this.RenameStyleDifferentInOnlySpaces(rtf);
var document = provider.Import(rtf);
...
private string RenameStyleDifferentInOnlySpaces(string rtf)
{
HashSet<string> styles = new HashSet<string>();
string pattern = @"{\\(?:\*\\c)?s([0-9]+)[^}]*\n?[^}]*\\[^' ]* ?'?([^;]*)";
var matches = Regex.Matches(rtf, pattern);
foreach (Match match in matches)
{
string styleName = match.Groups[2].Value.Replace(" ", string.Empty);
if (styles.Contains(styleName))
{
styleName = this.ReplaceOldStyleName(ref rtf, styles, match).Replace(" ", string.Empty);
}
styles.Add(styleName);
}
return rtf;
}
private string ReplaceOldStyleName(ref string rtf, HashSet<string> styles, Match match)
{
string oldStyleName = match.Groups[2].Value;
StringBuilder styleNameBuilder = new StringBuilder(oldStyleName + "0");
while (styles.Contains(styleNameBuilder.ToString().Replace(" ", string.Empty)))
{
styleNameBuilder.Append("0");
}
string oldMatch = match.Groups[0].Value;
string newMatch = oldMatch.Replace(oldStyleName, styleNameBuilder.ToString());
rtf = rtf.Replace(oldMatch, newMatch);
return styleNameBuilder.ToString();
}
StackOverflowException when importing a document with style based on itself.
Use the following code to strip the faulty "based on" definition from the RTF:
RtfFormatProvider provider = new RtfFormatProvider();
var rtf = File.ReadAllText(ofd.FileName);
rtf = this.ReplaceSelfBasedOnStyle(rtf);
this.flowDocument = provider.Import(rtf);
...
private string ReplaceSelfBasedOnStyle(string rtf)
{
string pattern = @"{[\n]*\\s[0-9]+[^;]* \\\w* (Normal);}";
var matches = Regex.Matches(rtf, pattern);
foreach (Match match in matches)
{
string oldValue = match.Value;
string newValue = oldValue.Replace(@"\sbasedon0 ", string.Empty);
rtf = rtf.Replace(oldValue, newValue);
}
return rtf;
}
When mailmerging a document, with nested mail merge group which starts inside a table and ends outside the table, a NullReferenceException is thrown: "System.NullReferenceException: 'Object reference not set to an instance of an object.' firstParagraphInTemplate was null."
Workaround: move the group end (EndGroup, TableEnd, RangeEnd, or GroupEnd) merge field inside the table where the group starts.
Using a RadFlowDocumentEditor to add a page break and then insert a table, adds an additional paragraph in between.
As a workaround you can call the CleanParagraphsBeforeTablesOnNewPage() method:
private void CleanParagraphsBeforeTablesOnNewPage()
{
List<Paragraph> paragraphs = this.flowDocument.EnumerateChildrenOfType<Paragraph>().ToList();
foreach (var paragraph in paragraphs)
{
BlockContainerBase parent = (BlockContainerBase)paragraph.Parent;
int paragraphIndex = parent.Blocks.IndexOf(paragraph);
int blocksCount = parent.Blocks.Count;
bool isAfterPageBreak = paragraphIndex > 0 && this.PreviousBlockEndsWithPageBreak(parent.Blocks[paragraphIndex - 1]);
int nextIndex = paragraphIndex + 1;
bool nextBlockIsTable = nextIndex < blocksCount && parent.Blocks[nextIndex] is Table;
if (isAfterPageBreak && nextBlockIsTable)
{
parent.Blocks.Remove(paragraph);
}
}
}
private bool PreviousBlockEndsWithPageBreak(BlockBase blockBase)
{
bool isLastInlinePageBreak = false;
bool isParagraph = blockBase is Paragraph;
if (isParagraph)
{
Paragraph paragraph = (Paragraph)blockBase;
InlineBase lastInline = paragraph.Inlines.Last();
bool isBreak = lastInline is Break;
if (isBreak)
{
isLastInlinePageBreak = ((Break)lastInline).BreakType == BreakType.PageBreak;
}
}
return isLastInlinePageBreak;
}