I've been using some code I found here, to try and change the case of text in a flow document. It changes the text properly however all the formatting is lost (bold, italics, etc) and when I save the document to a XML file all the text ends up in the first Run of the document and all the other Run's are empty.
private void ChangeCase()
{
TextPointer start = mergedDocument.ContentStart;
TextPointer end = mergedDocument.ContentEnd;
List<TextRange> textToChange = SplitToTextRanges(start, end);
ChangeCaseToAllRanges(textToChange);
}
private List<TextRange> SplitToTextRanges(TextPointer start, TextPointer end)
{
List<TextRange> textToChange = new List<TextRange>();
var previousPointer = start;
for (var pointer = start; (pointer != null && pointer.CompareTo(end) <= 0); pointer = pointer.GetPositionAtOffset(1, LogicalDirection.Forward))
{
var contextAfter = pointer.GetPointerContext(LogicalDirection.Forward);
var contextBefore = pointer.GetPointerContext(LogicalDirection.Backward);
if (contextBefore != TextPointerContext.Text && contextAfter == TextPointerContext.Text)
{
previousPointer = pointer;
}
if (contextBefore == TextPointerContext.Text && contextAfter != TextPointerContext.Text && previousPointer != pointer)
{
textToChange.Add(new TextRange(previousPointer, pointer));
previousPointer = null;
}
}
textToChange.Add(new TextRange(previousPointer ?? end, end));
return textToChange;
}
private void ChangeCaseToAllRanges(List<TextRange> textToChange)
{
Func<string, string> caseChanger;
ComboBoxItem cbi = cb_Case.SelectedItem as ComboBoxItem;
var textInfo = CultureInfo.CurrentUICulture.TextInfo;
if (cbi == null || (string)cbi.Tag == "none")
{
return;
}
else if((string)cbi.Tag == "title")
{
caseChanger = (text) => textInfo.ToTitleCase(text);
}
else if ((string)cbi.Tag == "upper")
{
caseChanger = (text) => textInfo.ToUpper(text);
}
else if ((string)cbi.Tag == "lower")
{
caseChanger = (text) => textInfo.ToLower(text);
}
else
return;
foreach (var range in textToChange)
{
if (!range.IsEmpty && !string.IsNullOrWhiteSpace(range.Text))
{
System.Diagnostics.Debug.WriteLine("Casing: " + range.Text);
System.Diagnostics.Debug.WriteLine("\tat: " +
range.Start.GetOffsetToPosition(mergedDocument.ContentStart) +
" ," +
range.End.GetOffsetToPosition(mergedDocument.ContentStart));
range.Text = caseChanger(range.Text);
}
}
}
I can't see any reason why this code isn't working properly. It looks like the textpointers in the textrange object are being redirected to the beginning of the document.