Datagridview Undo,Redo 셀 스타일까지 적용

안녕하세요! c# 독학중인 초급개발자입니다.

Datagridview를 자주 사용하고 있습니다. 하지만 윈폼 컨트롤의 몇가지 한계를 느끼고 WPF를 사용할 까 고민중이긴 하지만 현재 진행했던게 아쉬워 좀 더 알아보고자 질문을 올립니다!

Datagridview에서 Undo, Redo를 구현해서 사용중입니다. 하지만 셀스타일까지 함께 기억하고 돌아갔으면 하는데 참고할만한 예제나 방법이 있을까요?

지금은 Stack을 사용해 데이터만 적용할 수 있는 형태입니다!
도움 주시면 감사하겠습니다!

 public void Push()
        {
            dtStack.Push(GetDataTableFromDGV(this));
        }
        public void DoInit(bool isDrag = true)
        {
            dtStack.Clear();
            dtStack.Push(GetDataTableFromDGV(this));
            //Redo, Undo event
            //this.CellValidated += new System.Windows.Forms.DataGridViewCellEventHandler(this.MultiHeaderGrid_CellValidated);
            this.CellValueChanged += new System.Windows.Forms.DataGridViewCellEventHandler(this.MultiHeaderGrid_CellValueChanged);
        }
        Stack<DataTable> dtStack = new Stack<DataTable>();
        int RecordIndex = 0;
        bool UndoRedo = false;

        public DataTable GetDataTableFromDGV(DataGridView dgv)
        {
            var dt = new DataTable();

            foreach (DataGridViewColumn column in dgv.Columns)
            {
                dt.Columns.Add(column.Name);
            }

            object[] cellValues = new object[dgv.Columns.Count];

            foreach (DataGridViewRow row in dgv.Rows)
            {
                for (int i = 0; i < row.Cells.Count; i++)
                {
                    cellValues[i] = row.Cells[i].Value;
                }
                dt.Rows.Add(cellValues);
            }
            return dt;
        }

        public void datatablaToDataGrid(DataGridView dgv, DataTable datatable)
        {
            try
            {
                for (int i = 0; i < datatable.Rows.Count; i++)
                {
                    for (int j = 0; j < datatable.Columns.Count; j++)
                    {
                        dgv.Rows[i].Cells[j].Value = datatable.Rows[i][j].ToString();
                    }
                }
            }
            catch
            { }
        }

        public bool isPush = true;
        public void MultiHeaderGrid_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            if (!isPush)
                return;

            if (UndoRedo)
                return;

            try
            {
                DataGridView dgv = (DataGridView)sender;
                int r = e.RowIndex;
                int c = e.ColumnIndex;
                if (dgv.Rows[r].Cells[c].Value != null)
                {
                    string dgvResult = dgv.Rows[r].Cells[c].Value.ToString();
                    string dtResult = dtStack.ElementAt(RecordIndex).Rows[r][c].ToString();
                    if (dgvResult != dtResult)
                    {
                        while (RecordIndex > 0)
                        {
                            dtStack.Pop();
                            RecordIndex--;
                        }

                        dtStack.Push(GetDataTableFromDGV(this));
                    }
                }
            }
            catch
            { }
        }

        private void Undo()
        {
            if (dtStack.Count > RecordIndex + 1)
            {
                UndoRedo = true;
                datatablaToDataGrid(this, dtStack.ToList()[++RecordIndex]);
                UndoRedo = false;
            }
        }
        private void Redo()
        {
            if (0 < RecordIndex - 1)
            {
                UndoRedo = true;
                datatablaToDataGrid(this, dtStack.ToList()[--RecordIndex]);
                UndoRedo = false;
            }

        }