Similar to MS-Excel application, Spread for Windows Forms provides several keyboard shortcuts, like Ctrl + C for Copy, Ctrl + V for Paste and Ctrl + Z for Undo operations. Undo is an important operation while working with any editing control whether it is a Text Editor or a Grid with editing capabilities. Spread also provides the option to revert any changes done in the grid.

When a user does any modifications in Spread, the actions performed by user is added to the undo stack that is managed by the UndoManager Class. Later when the user presses Ctrl + Z, the UndoManager pops the last action in the undo stack and performs the undo for the same. For more details on UndoManager Class, you can refer to the following Documentation.

However, there are some custom actions in Spread which cannot be directly reverted in Spread. For examples, changing the Font or Border of a cell, adding and deleting rows etc. All these actions are implemented in the code behind and are mostly provided to the user on a button click or as part of a context menu. As a result, they are not added to the Undo stack by the UndoManager.

To get these actions into the Undo stack, you would need to:

  1. Create a Class inherited from the UndoAction Class which implements SaveUndoState, PerformUndoAction, and Undo methods.

  2. The PerformUndoAction method is called by the UndoManager class to perform the custom action and add it to the Undo stack of the UndoManager class so that it can be later undone.

  3. The Undo method is called to undo the Custom action.

  4. In between both these there is a method called SaveUndoState that saves the state of the Spread before any action is performed i.e it saves any information i.e. later required to undo the custom action performed. This method is called by the PerfomUndoAction method to save the necessary information required to perform the undo and later perform the action.




public class FontAction : FarPoint.Win.Spread.UndoRedo.UndoAction
{
FarPoint.Win.Spread.SheetView sheetView;
Font ofont, nfont;
int row, col;

public FontAction(){}

public FontAction(FarPoint.Win.Spread.SheetView sheetView, Font f)
{
this.sheetView = sheetView;
this.nfont = f;
}

public override bool PerformUndoAction(object sender)
{
FarPoint.Win.Spread.SpreadView spreadView = null;
if (sender is FarPoint.Win.Spread.SpreadView)
{
spreadView = (FarPoint.Win.Spread.SpreadView)sender;
}
else
{
return false;
}

if (sheetView == null)
{
sheetView = spreadView.GetSheetView();
}

if ((SaveUndoState()) & (sheetView != null))
{
sheetView.ActiveCell.Font = nfont;
return true;
}
return false;
}

protected override bool SaveUndoState()
{
if ((sheetView != null))
{
if (sheetView.ActiveCell.Font == null)
{
ofont = new Font("Microsoft Sans Serif", 8.25f, FontStyle.Regular);
row = sheetView.ActiveCell.Row.Index;
col = sheetView.ActiveCell.Column.Index;
}
else
{
ofont = sheetView.ActiveCell.Font;
row = sheetView.ActiveCell.Row.Index;
col = sheetView.ActiveCell.Column.Index;
}
}
return (ofont != null);
}

public override bool Undo(object sender)
{
FarPoint.Win.Spread.SpreadView spreadView = null;
if (sender is FarPoint.Win.Spread.SpreadView)
{
spreadView = (FarPoint.Win.Spread.SpreadView)sender;
}
else
{
return false;
}

if ((ofont != null))
{
sheetView.Cells[row,col].Font = ofont;
return true;
}
return false;
}
}



Once, implementation of the Class to handle the custom action is done, you can create the instance of the same. New instance for this custom Class  can be used as a parameter for the static method PerformUndoAction of the UndoManager Class which would call the PerformUndoAction for the class whose instance is passed to it. This would further call the SaveUndoState method to save the Spread state and perform the action. Later, you can undo the same by simply pressing the shortcut key Ctrl + Z.


private void button1_Click(object sender, EventArgs e)
{
Font f1 = new Font("Broadway", 12f,FontStyle.Bold);
FontAction sra = new FontAction(fpSpread1.Sheets[0], f1);
fpSpread1.UndoManager.PerformUndoAction(sra);
}


Refer to the attached sample for the implementation.

Download Sample C#
Download Sample VB.Net