How to undo a custom action?

https://help.syncfusion.com/wpf/spreadsheet/interactive-features#undoredo


I'd like to encapsulate the following code into an undo function.

When Ctrl + Z is pressed, it should execute the undo operation.


SpreadsheetControl.SfSpreadsheet.ActiveSheet.Range[cell].CellStyle.Color = color;

 SpreadsheetControl.SfSpreadsheet.ActiveGrid.InvalidateCell(newRange, true);



4 Replies

SG Santhosh Govindasamy Syncfusion Team October 22, 2024 03:07 PM UTC

Hi crosslife,

Thank you for reaching out.

Based on the provided information and your code snippet, as per our understanding, you're looking to implement an undo function for programmatically applying cell color in the SfSpreadsheet when Ctrl + Z is pressed.

Please note that you cannot directly perform an undo for this programmatic function. However, this can be achieved by utilizing the HistoryManager and HistoryFormatCommand, which support undo/redo operations. The HistoryManager can manage the undo stack, and by pushing HistoryFormatCommand instances to it, you can enable the undo functionality.

 
Code Snippet:

private void OnRefreshClicked(object sender, RoutedEventArgs e)

 {

 

     //Cell Range

     ribbon.SfSpreadsheet.ActiveSheet.Range["A1:B4"].CellStyle.Color = System.Drawing.Color.Red;

 

 

     GridRangeInfo gridRangeInfo = GridRangeInfo.Cells(1, 1, 4, 2);

 

     var range = gridRangeInfo;

     for (int left = range.Left; left <= range.Right; left++)

     {

         for (int top = range.Top; top <= range.Bottom; top++)

         {

             spreadsheet.HistoryManager.Push(new HistoryFormatCommand(spreadsheet.ActiveGrid.Worksheet[top, left], spreadsheet));

         }

     }

 

 

     ribbon.SfSpreadsheet.ActiveSheet.Range["A1:B4"].CellStyle.Color = System.Drawing.Color.Yellow;

 

     ribbon.SfSpreadsheet.ActiveGrid.InvalidateCell(GridRangeInfo.Cells(1, 1, 4, 2), true);

 

     //Single Cell

     spreadsheet.ActiveSheet[2, 2].CellStyle.Color = System.Drawing.Color.Red;

     this.spreadsheet.HistoryManager.Push(new HistoryFormatCommand(spreadsheet.ActiveSheet[2, 2], this.spreadsheet));

 

     spreadsheet.ActiveSheet[2, 2].CellStyle.Color = System.Drawing.Color.Yellow;

 

     spreadsheet.ActiveGrid.InvalidateCell(2, 2);

 

 }


If we have misunderstood your requirement, please explain it in detail. This will help us proceed further.


For your reference, we have attached the sample. Please take a look at it.

Regards,
Santhosh.G


Attachment: SpreadSheetDemo_b79f0f22.zip


CR crosslife October 23, 2024 03:49 AM UTC

Can these HistoryFormatCommand instances be consolidated into one, so that when undoing, the color of the entire Range can be restored at once?



GridRangeInfo gridRangeInfo = GridRangeInfo.Cells(1, 1, 4, 2);


            var range = gridRangeInfo;

            for (int left = range.Left; left <= range.Right; left++)

            {

                for (int top = range.Top; top <= range.Bottom; top++)

                {

                    spreadsheet.HistoryManager.Push(new HistoryFormatCommand(spreadsheet.ActiveGrid.Worksheet[top, left], spreadsheet));

                }

            }



CR crosslife October 23, 2024 03:56 AM UTC

It seems that it's not refreshing after the undo operation. Is there a way to manually fix this?



ublic override void Execute(CommandMode mode)

    {

      switch (mode)

      {

        case CommandMode.Undo:

          this.SfSpreadsheet.HistoryManager.RedoStack.Push((HistoryCommandBase) new HistoryFormatCommand(this.Range, this.SfSpreadsheet));

          break;

        case CommandMode.Redo:

          this.SfSpreadsheet.HistoryManager.UndoStack.Push((HistoryCommandBase) new HistoryFormatCommand(this.Range, this.SfSpreadsheet));

          break;

      }

      this.Range.IndentLevel = this.IndentLevel;

      this.Range.CellStyle.Color = this.ExistingBackColor;

      base.Execute(mode);

    }



SG Santhosh Govindasamy Syncfusion Team October 23, 2024 07:30 AM UTC

Hi crosslife,

Thank you for your response.

Regarding your requirement to restore the colors of the entire range when performing an undo action, this can be achieved using the HistoryTransactionCommand. It allows all commands to be executed together as a single command, enabling the Undo or Redo functionality.

Code Snippet:

private void OnRefreshClicked(object sender, RoutedEventArgs e)

{

 

     //Cell Range

     ribbon.SfSpreadsheet.ActiveSheet.Range["A1:B4"].CellStyle.Color = System.Drawing.Color.Red;

     var ranges = new IRange[1];

     ranges[0] = spreadsheet.ActiveGrid.Worksheet["A1:B4"];

     GridRangeInfo gridRangeInfo1 = spreadsheet.ActiveGrid.Worksheet.Range["A1:B4"].ConvertExcelRangeToGridRange() as GridRangeInfo;

     //GridRangeInfo gridRangeInfo = GridRangeInfo.Cells(1, 1, 4, 2);

     spreadsheet.HistoryManager.Push(null);

     var range = gridRangeInfo1;

     for (int left = range.Left; left <= range.Right; left++)

     {

         for (int top = range.Top; top <= range.Bottom; top++)

         {

             spreadsheet.HistoryManager.Push(new HistoryFormatCommand(spreadsheet.ActiveGrid.Worksheet[top, left], spreadsheet));

         }

     }

 

     spreadsheet.HistoryManager.Push(new HistoryTransactionCommand(spreadsheet, ranges, spreadsheet.ActiveGrid.CurrentCell));

    

     ribbon.SfSpreadsheet.ActiveSheet.Range["A1:B4"].CellStyle.Color = System.Drawing.Color.Yellow;

 

     ribbon.SfSpreadsheet.ActiveGrid.InvalidateCell(GridRangeInfo.Cells(1, 1, 4, 2), true);


For your reference, we have attached the modified sample. Please take a look at it.

In your last update, you mentioned "Not refreshing after the Undo operation." We are unclear about the exact scenario, so to proceed further, kindly share more details. This will help us better understand the scenario.

Thank you for your cooperation, and we look forward to your response.

Regards,
Santhosh.G


Attachment: SpreadSheetDemo_ff68d615.zip

Loader.
Up arrow icon