0

I need my undo/redo code to function like the undo/redo features found in Microsoft Notepad, Microsoft Word etc. (I am creating a Word Processor).

Currently, my Undo and Redo code is working to an extent. But there are a number of issues with the undo/redo functions in my application. These are as follows:

If I type a sentence, such as "Hello, my name is Toby.", and then I undo the text (leaving Hello still on the document), I can only redo up to "is".

If I undo all the text in the document, I cannot redo any of the text. So if I again type "Hello, my name is Toby.", and then I undo that line, I cannot then redo any of the text.

I was hoping somebody could help me rectify these issues.

As of now, the code used by both Undo and redo is as follows:

    public struct UndoSection
    {
        public string Undo;
        public int Index;

        public UndoSection(int index, string undo)
        {
            Index = index;
            Undo = undo;
        }
 private void richTextBoxPrintCtrl1_TextChanged(object sender, EventArgs e)
        {
            {
                OldLength = richTextBoxPrintCtrl1.Text.Length; System.Text.RegularExpressions.MatchCollection wordColl = System.Text.RegularExpressions.Regex.Matches(richTextBoxPrintCtrl1.Text, "'?([a-zA-z'-]+)'?");
                counter.Text = wordColl.Count.ToString();
            }
            try
            {
                if (IsRedoUndo == false && (richTextBoxPrintCtrl1.Text.Substring(richTextBoxPrintCtrl1.Text.Length - 1, 1) == " " || richTextBoxPrintCtrl1.Text.Substring(richTextBoxPrintCtrl1.Text.Length - 1, 1) == ","))
                {
                    StackCount = StackCount + 1;
                    RTBRedoUndo[StackCount] = richTextBoxPrintCtrl1.Text;
                }
            }
            catch { }

        }
public string[] RTBRedoUndo;
        public int StackCount = 0;
        public int OldLength = 0;
        public int ChangeToSave = 5;
        public bool IsRedoUndo = false;

        public void RTBTextChanged()
        {
            if (richTextBoxPrintCtrl1.TextLength - OldLength >= ChangeToSave | richTextBoxPrintCtrl1.TextLength - OldLength <= ChangeToSave)
            {
                StackCount += 1;
                RTBRedoUndo[StackCount] = richTextBoxPrintCtrl1.Text;
            }

The undo code:

public void UndoCode()
        {
            IsRedoUndo = true;
            if (StackCount > 0 && RTBRedoUndo[StackCount - 1] != null)
            {
                StackCount = StackCount - 1;
                richTextBoxPrintCtrl1.Text = RTBRedoUndo[StackCount];
            }
        }

The redo code:

public void RedoCode()
        {
            if (IsRedoUndo == false && richTextBoxPrintCtrl1.Text.Substring(richTextBoxPrintCtrl1.Text.Length - 1, 1) == " ")

                IsRedoUndo = true;
            if (StackCount > 0 && RTBRedoUndo[StackCount + 1] != null)
            {
                StackCount = StackCount + 1;
                richTextBoxPrintCtrl1.Text = RTBRedoUndo[StackCount];
            }

I'm not too sure what to try, so I was hoping that somebody with more of a knowledge of programming could help me, as I'm still a novice and in my learning stages.

Thanks :o)

Toby
  • 377
  • 1
  • 10
  • 23
  • Well, this is probably way too advanced for a novice, but the best way to do an undo/redo operation is with the [Command design pattern](http://en.wikipedia.org/wiki/Command_pattern) – Pierre-Luc Pineault Apr 29 '13 at 22:44
  • Is there some reason you're rolling your own stack instead of simply using `System.Collections.Generic.Stack`? (You might for example be making your own stack as a learning exercise; but in that case: **extract the stack to its own class**. Your program will be much easier to understand and to test if you *separate the concerns* out into their own classes.) – Eric Lippert Apr 29 '13 at 23:05
  • I'm not really sure. I really just tried to piece stuff together and get it working. I can't believe how hard undo/redo is to get working.. – Toby Apr 29 '13 at 23:13
  • @Toby Undo/Redo is a *difficult* problem. It makes sense that it's hard! As Eric said, use the built-in stack class to help you get the stack logic right. Also, once you're using the built-in stack, you may find it useful to have *two* stacks, one for changes that can be undone, and one for changes that can be redone. Finally, while the command pattern is indeed useful, it's probably overkill here. – dlev Apr 29 '13 at 23:22

1 Answers1

0

You seem to be setting your stack count back to zero once you Undo. Thats why when u Redo it goes only up to the amount allowed -1 try

Undo Code

public void UndoCode()
    {
        IsRedoUndo = true;
        if (StackCount > 0 && RTBRedoUndo[StackCount] != null)
        {
            StackCount = StackCount - 1;
            richTextBoxPrintCtrl1.Text = RTBRedoUndo[StackCount+1];
        }
    }
ebolton
  • 1,126
  • 3
  • 14
  • 20
  • Hey. Thanks for the answer. Unfortunately, it did not seem to work, as it doesn't seem to allow redo to function correctly, and then also stops undo from functioning. – Toby Apr 29 '13 at 23:12
  • Okay no problem. yea experiment with the numbers. Usually it has something to do with the increments of the array or stack that you are using. – ebolton Apr 29 '13 at 23:15
  • Ah. Okay, I'll have a play around. Thanks. – Toby Apr 29 '13 at 23:16
  • Nothing seems to make a difference here.. :S – Toby Apr 29 '13 at 23:20