I'm writing a video subtitling app. It contains a RichTextBox editor. When I open a text file from disk, I process it in a method that returns a FlowDocument with the individual Paragraph and Run objects, and lastly assign that document to the RichTextBox.Document property. The issue I'm having is that if I use the built-in Undo function before assigning the created FlowDocument to the RichTextBox.Document property (i. e. when the app just started and the RichTextBox is blank), everything works fine, and I can undo multiple actions (memory permitting, since the UndoLimit of the RichTextBox is set to -1). However, after assigning the FlowDocument returned from my method to the RichTextBox.Document, I can only undo the last action.

I have tried setting the UndoLimit = 0 and then UndoLimit = -1, to reset the undo stack after assigning the FlowDocument. I also tried setting the IsUndoEnable property to false and then to true. Also tried to modify the method to avoid assigning the FlowDocument directly to the Document property of the RichTextBox. Instead, I tried adding the individually created blocks directly to the RichTextBox.Document.Blocks property, wrapped between BeginChange() and EndChange() methods. None of these worked.

This is the assignment code:

// If the method returned a valid document...
if (flowDocument != null)
{
   // Clear rich text box.
   Editor.Document.Blocks.Clear();
   // Set document.
   Editor.Document = flowDocument; 
   // Set flag.
   DOCUMENT_LOADED = true;
}

The method to create the FlowDocument that is assigned to the RichTextBox.Document property:

public static FlowDocument CreateFlowDocumentFromText(string text)
{
   // Create return document.
   FlowDocument document = null;
   // Check for valid string.
   if (!String.IsNullOrEmpty(text))
   {
      // Create document.
      document = new FlowDocument();
      // Split it in new lines and remove empty lines.
      string[] paragraphs = text.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None);

      // For each paragraph.
      foreach (string paragraph in paragraphs)
      {
         // Create paragraph object.
         Paragraph paragraphContent = new Paragraph(new Run(paragraph));
         // Check maximum length.
         paragraphContent.Background = Utilities.CheckParagraphLength(paragraphContent);
         // Add paragraph to editor.
         document.Blocks.Add(paragraphContent);
      }
   }
   return document;
}

And the alternate method I tried to avoid the document assignment:

public static void LoadTextEditor(RichTextBox editor, string text)
{
   // Check for valid string.
   if (!String.IsNullOrEmpty(text))
      {
      // Split it in new lines and remove empty lines.
      string[] paragraphs = text.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None);

      // For each paragraph.
      foreach (string paragraph in paragraphs)
      {
         // Create paragraph object.
         Paragraph paragraphContent = new Paragraph(new Run(paragraph));
         // Check maximum length.
         paragraphContent.Background = Utilities.CheckParagraphLength(paragraphContent);
         // Add paragraph to editor.
         editor.BeginChange();
         editor.Document.Blocks.Add(paragraphContent);
         editor.EndChange();
      }
   }
}

In all cases, the expected result was to be able to undo multiples changes, but the result was that only the last change was undoable. Furthermore, after the document assignment, the RichTextBox acts as if UndoLimit = 1, since no matter what other changes I do, I can only undo the most recent one.

0 Answers