在devexpress grid中设计undo

在m_gridView_ValidatingEditor中得到cell修改之前的值,然后保存起来。


        private void m_toolUndo_Click(object sender, EventArgs e)
        {
            if (m_undoInfo.Available)
            {
                DataTable dt = m_gridControl.DataSource as DataTable;
                dt.AcceptChanges();
                ActionData actionData = m_undoInfo.Pop();

                CellActionData cellActionData = actionData as CellActionData;
                if (cellActionData != null)
                {
                    switch (cellActionData.ActionType)
                    {
                        case EnuActionType.ChangeCell:
                            foreach (CellActionDataItem dataItem in cellActionData.DataItemList)
                            {
                                DataRow[] rows = dt.Select("AutoGen=" + dataItem.AutoGenId);
                                if (rows.Length > 0)
                                {
                                    rows[0][dataItem.ColumnName] = dataItem.OrgValue;
                                }
                            }
                            break;

                        case EnuActionType.AddRow:
                            foreach (CellActionDataItem dataItem in cellActionData.DataItemList)
                            {
                                DataRow[] rows = dt.Select("AutoGen=" + dataItem.AutoGenId);
                                if (rows.Length > 0)
                                {
                                    dt.Rows.Remove(rows[0]);
                                }
                            }
                            break;

                        case EnuActionType.DeleteRow:
                            foreach (CellActionDataItem dataItem in cellActionData.DataItemList)
                            {
                                DataRow[] rows = dt.Select("AutoGen=" + dataItem.AutoGenId);
                                if (rows.Length > 0)
                                {
                                    rows[0][dataItem.ColumnName] = dataItem.OrgValue;
                                }
                                else
                                {
                                    DataRow drNew = dt.NewRow();
                                    drNew[dataItem.ColumnName] = dataItem.OrgValue;
                                    dt.Rows.Add(drNew);
                                }
                            }

                            break;
                    }
                }
                else
                {
                    ColumnActionData columnActionData = actionData as ColumnActionData;
                    if (columnActionData != null)
                    {
                        int idxOrdinal = dt.Columns.IndexOf(columnActionData.ColumnName);
                        foreach (ColumnActionDataItem dataItem in columnActionData.DataItemList)
                        {
                            DataRow[] rows = dt.Select("AutoGen=" + dataItem.AutoGenId);
                            if (rows.Length > 0)
                            {
                                rows[0][idxOrdinal] = dataItem.OrgValue;
                            }
                        }
                    }
                }

                dt.AcceptChanges();
            }
            else
            {
                MsgHelper.Alert("No undo info");
            }
        }

        private void m_gridView_ValidatingEditor(object sender, DevExpress.XtraEditors.Controls.BaseContainerValidateEditorEventArgs e)
        {
            CellActionData cellActionData = new CellActionData(EnuActionType.ChangeCell);
            DataRow dr = m_gridView.GetDataRow(m_gridView.FocusedRowHandle);
            cellActionData.DataItemList.Add(new CellActionDataItem(m_gridView.FocusedColumn.FieldName, Convert.ToInt32(dr["AutoGen"]), dr[m_gridView.FocusedColumn.FieldName]));
            m_undoInfo.Push(cellActionData);

        }

 

        private void m_gridControl_EmbeddedNavigator_ButtonClick(object sender, DevExpress.XtraEditors.NavigatorButtonClickEventArgs e)
        {
            if (e.Button.ButtonType == DevExpress.XtraEditors.NavigatorButtonType.Append)
            {
                m_gridView.PostEditor();
                m_gridView.UpdateCurrentRow();
                DataTable dt = m_gridControl.DataSource as DataTable;
                if (dt != null)
                {
                    dt.AcceptChanges();

                    FrmSelectFileIdAndSheetName frm = new FrmSelectFileIdAndSheetName(dt);
                    frm.OnOK += new EventHandler<SelectFileIdAndSheetNameArgs>(frm_OnOK);
                    frm.ShowDialog();
                }

                e.Handled = true;
            }
            else if (e.Button.ButtonType == DevExpress.XtraEditors.NavigatorButtonType.Remove)
            {
                int[] arrRowHandle = m_gridView.GetSelectedRows();
                CellActionData cellActionData = new CellActionData(EnuActionType.DeleteRow);
                foreach(int rowHandle in arrRowHandle)
                {
                    DataRow dr = m_gridView.GetDataRow(rowHandle);
                    foreach (DataColumn dataCol in dr.Table.Columns)
                    {
                        cellActionData.DataItemList.Add(new CellActionDataItem(dataCol.ColumnName, Convert.ToInt32(dr["AutoGen"]), dr[dataCol]));
                    }

                }
                m_undoInfo.Push(cellActionData);
            }

        }

        private void frm_OnOK(object sender, SelectFileIdAndSheetNameArgs e)
        {
            DataTable dt = m_gridControl.DataSource as DataTable;
            DataRow dr = dt.NewRow();
            dr[m_colOriginalFileId.FieldName] = e.FileId;
            dr[m_colSheetName.FieldName] = e.SheetName;

            CellActionData cellActionData = new CellActionData(EnuActionType.AddRow);
            cellActionData.DataItemList.Add(new CellActionDataItem("AutoGen", Convert.ToInt32(dr["AutoGen"]), dr["AutoGen"]));
            m_undoInfo.Push(cellActionData);

            dt.Rows.Add(dr);

        }

 

-----------------------------------------

 

    class UndoInfo
    {
        private LinkedList<ActionData> m_UndoList = new LinkedList<ActionData>();
        private int m_capacity = 10;

        public event EventHandler ChangedHandler = null;

        public void PushColumn(EnuActionType enActionType, DataTable dt, string columnName)
        {
            if (dt == null || dt.Rows.Count == 0)
            {
                return;
            }
            int idxOrdinal = dt.Columns.IndexOf(columnName);
            ColumnActionData columnActionData = new ColumnActionData(enActionType, columnName);
            foreach (DataRow dr in dt.Rows)
            {
                columnActionData.DataItemList.Add(new ColumnActionDataItem(Convert.ToInt32(dr["AutoGen"]), dr[idxOrdinal]));
            }

            Push(columnActionData);
        }

        public void Push(ActionData curVal)
        {
            if (curVal == null)
            {
                return;
            }
            CellActionData cellActionData = curVal as CellActionData;
            if (cellActionData != null)
            {
                if (cellActionData.DataItemList.Count == 0)
                {
                    return;
                }
            }
            else
            {
                ColumnActionData columnActionData = curVal as ColumnActionData;
                if (columnActionData != null)
                {
                    if (columnActionData.DataItemList.Count == 0)
                    {
                        return;
                    }
                }
                else
                {
                    throw new NotImplementedException("Not implemented.");
                }
            }

            m_UndoList.AddLast(curVal);

            while (m_UndoList.Count > m_capacity)
            {
                m_UndoList.RemoveFirst();
            }

            Notify();
        }

        public int Count
        {
            get
            {
                return m_UndoList.Count;
            }
        }

        public bool Available
        {
            get
            {
                return (m_UndoList.Count > 0);
            }
        }

        public ActionData Pop()
        {
            if (Available)
            {
                ActionData tmp = m_UndoList.Last.Value;
                m_UndoList.RemoveLast();
                Notify();
                return tmp;
            }
            else
            {
                throw new InvalidOperationException("Undo list is empty.");
            }
        }

        public void Clear()
        {
            m_UndoList.Clear();
            Notify();
        }

        private void Notify()
        {
            if (ChangedHandler != null)
            {
                ChangedHandler(null, null);
            }
        }

    }

    enum EnuActionType
    {
        ChangeCell,
        AddRow,
        DeleteRow,
    }

    class ActionData
    {
        public ActionData(EnuActionType enActionType)
        {
            ActionType = enActionType;
        }

        public readonly EnuActionType ActionType;
    }

    class CellActionData : ActionData
    {
        public CellActionData(EnuActionType enActionType)
            : base(enActionType)
        {
            DataItemList = new List<CellActionDataItem>();
        }

        public readonly List<CellActionDataItem> DataItemList;

    }

    class ColumnActionData : ActionData
    {
        public ColumnActionData(EnuActionType enActionType, string strColumnName)
            : base(enActionType)
        {
            ColumnName = strColumnName;
            DataItemList = new List<ColumnActionDataItem>();
        }

        public readonly string ColumnName;

        public readonly List<ColumnActionDataItem> DataItemList;

    }

    class CellActionDataItem
    {
        public string ColumnName;
        public int AutoGenId;
        public object OrgValue;

        public CellActionDataItem(string strColumnName, int genId, object val)
        {
            ColumnName = strColumnName;
            AutoGenId = genId;
            OrgValue = val;
        }
    }

    class ColumnActionDataItem
    {
        public int AutoGenId;
        public object OrgValue;

        public ColumnActionDataItem(int genId, object val)
        {
            AutoGenId = genId;
            OrgValue = val;
        }
    }

 

 

==================================

当仅仅只是粗略的整个状态进行保存用如下代码:


    class UndoInfo
    {
        private LinkedList<DataTable> m_UndoList = new LinkedList<DataTable>();
        private int m_capacity = 1;

        public event EventHandler ChangedHandler = null;

        public void Push(DataTable curVal)
        {
            DataTable objNew = null;
            if (curVal != null)
            {
                using (MemoryStream stream = new MemoryStream())
                {
                    BinaryFormatter formatter = new BinaryFormatter();
                    formatter.Serialize(stream, curVal);
                    stream.Flush();

                    stream.Position = 0;
                    objNew = formatter.Deserialize(stream) as DataTable;
                }
            }
            m_UndoList.AddLast(objNew);

            while (m_UndoList.Count > m_capacity)
            {
                m_UndoList.RemoveFirst();
            }

            Notify();
        }

        public bool Available
        {
            get
            {
                return (m_UndoList.Count > 0);
            }
        }

        public DataTable Pop()
        {
            if (Available)
            {
                DataTable tmp = m_UndoList.Last.Value;
                m_UndoList.RemoveLast();
                Notify();
                return tmp;
            }
            else
            {
                throw new InvalidOperationException("Undo list is empty.");
            }
        }

        public void Clear()
        {
            m_UndoList.Clear();
            Notify();
        }

        private void Notify()
        {
            if (ChangedHandler == null)
            {
                ChangedHandler(null, null);
            }
        }

    }

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值