Search code examples
c#wpfcommand-pattern

Command pattern - undo function in textbox issue


I have several TextBoxes which share the same TextChanged listener.

private void text1_TextChanged(object sender, TextChangedEventArgs e)
{
    CommandManager.InvokeExecute(new SaveUpdateCommand((TextBox)sender));
}

When an event occures, the old TextBox object is being put onto a stack here:

internal static class CommandManager
{
    private static Stack<Command> commandStack = new Stack<Command>();

    internal static void InvokeExecute(Command cmd)
    {
        cmd.Execute();
        commandStack.Push(cmd);
    }

    internal static void InvokeUndo()
    {
        if (commandStack.Count > 0) commandStack.Pop().Undo();
    }
}

However for the undo to work i need to click the InvokeUndo button twice and i can not figure out why. Besides the necessary doubleclick all works well. Here is the Command implementation.

internal class SaveUpdateCommand : Command
{
    private TextBox textBox;
    private string oldText;

    public SaveUpdateCommand(TextBox textBox)
    {
        this.textBox = textBox;
        this.oldText = textBox.Text;
    }

    internal override void Execute()
    {
        //Not implemented within this command.
    }

    internal override void Undo()
    {
        textBox.Text = oldText;
    }
}

Thank you for any insight. The GUI was done with VS2015 designer with WPF.


Solution

  • I've written such a undo/do-again class quite long ago && recognized exactly the same error as you do.

    IMHO this depends on the following:

    • you change the text of the textbox
    • the textbox fires the exe command:    <------------------------------+
      • your list gets a new item with the command item                                  |
      • the command item contains the actual text                                           |
    • now you click the undo button:                                                                    |
      • you recieve the old text of the textbox                                                   |
      • you assign the old text to the textbox                                                    |
      • assigning the old text to the textbox the text obviously changes          |
      • the textbox sends a new exe command     ------------------------+
      • now you have the same item in the list again which you ar looking at the moment

    This is why you have to double click your undo button befroe you think the text changes...

    Actually the text changed, but as it stays the same you don't recognize it by any UI Update.

    You see the nice ASCII arrow?? ^^