Click here to Skip to main content
15,886,799 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hey Codeproject,

I know this might be an odd one. I'm creating my own custom control, and I'm currently at the stage where I can finally impliment some functions. One of the functions I want to add is "undo" and "redo", now I've never done this before, and my curiosity got the better of me when I thought about using a list containing "delegate" functions to make a simple undo-redo function.

Now, I'm not sure if delegate is the right word for it, what I'm pretty much trying to do is the following:

C#
public List<Delegate> Undo { get; set; }

       private void SetText(int Index, string String)
        {
            Text.Insert(Index, String);
        }


C#
private void RemoveText(index, String)
{
   Undo.Add(SetText(index, string));
}


I want to be able to add to the "Undo" list the function SetText(Index, "String"), and then call it from the function Undo();.

C#
private void UndoFunction()
        {
            Undo[Undo.Count - 1]();
            Undo.Remove(Undo[Undo.Count - 1]);
        }


Does anyone know if something like this is possible? I may just find a workaround if it's not directly possible but it would be great if it was.

Regards, - Eddie

What I have tried:

C#
public List<Delegate> Undo { get; set; }

       private void SetText(int Index, string String)
        {
            Text.Insert(Index, String);
        }
Posted
Updated 4-May-17 9:59am
v5

You can do it using the Action delegate

List<Action> Undo = new List<Action>();

Undo.Add(() => SetText(1, "Hello"));
Undo.Add(() => SetText(2, "World"));


foreach (var u in Undo)
{
    u();
}


Or you can use interfaces to create classes that are suited to different types of undo action. This method is more flexible as you can have different classes responsible for different types of action with their own parameters etc

public interface IUndo
{
    void Undo();
}

public class SetTextUndo : IUndo
{
    public int Index { get; set; }
    public string Text { get; set; }

    public void Undo()
    {
        Console.WriteLine("Undo for {0} {1}", this.Index, this.Text);
    }
}

public class FormattingUndo : IUndo
{
    public enum FormatTypeEnum
    {
        Bold,
        Italic,
        Underline
    }

    public FormatTypeEnum FormatType { get; set; }

    public void Undo()
    {
        Console.WriteLine("Undo formatting {0}", this.FormatType);
    }
}


List<IUndo> Undo = new List<IUndo>();

Undo.Add(new SetTextUndo { Index = 1, Text = "Hello" });
Undo.Add(new SetTextUndo { Index = 2, Text = "World" });
Undo.Add(new FormattingUndo { FormatType = FormattingUndo.FormatTypeEnum.Italic });

foreach (var u in Undo)
{
    u.Undo();
}
 
Share this answer
 
Comments
It's Eddie! 4-May-17 16:38pm    
Excellent, exactly what I was asking for. Thank you a lot.
Maciej Los 5-May-17 6:04am    
5ed!
BillWoodruff 11-Jan-22 23:30pm    
+5
 
Share this answer
 
Comments
It's Eddie! 4-May-17 16:41pm    
Very helpful links, thank you.
Maciej Los 5-May-17 6:04am    
You're very welcome.
BillWoodruff 11-Jan-22 23:28pm    
+5 very useful !
Maciej Los 12-Jan-22 4:49am    
Thank you, Bill.
As you see, this answer was written 4.5 year ago...
BillWoodruff 12-Jan-22 4:58am    
excellent answers are timeless :) ... and deserve up-votes !
Maybe you can use Activator, see this example: Activator Class (System)[^]
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900