ArcEngine/Arcgis Element 撤销Undo和重做Redo

点击源码下载

效果图:               

   

 

在制图pagelayout环境下有两种方式可以实现undo和redo,

方法一:

            该方法是基于自己实现的一些element操作,不使用arcgis 自带的一些命令按钮  

步骤1:在制图启动的时候,需要New 一个 IOperationStack对象(这是一个堆栈操作集合),用于存放Element的操作。

  IOperationStack pOperationStack = new ControlsOperationStackClass();

  步骤2:然后定义一个类ElementUndoRedo类,然后实现IOpreation接口,然后在该类文件下面再定义一个ElementOpreation类。如下代码所示:

    class ElementUndoRedo : IOperation
    {
        public virtual bool CanRedo
        {
            get
            {
                return true;
            }
        }

        public virtual bool CanUndo
        {
            get
            {
                return true;
            }
        }

        public virtual string MenuString
        {
            get;
        }
        public virtual void Do()
        {
        }
        public virtual void Redo()
        {
        }
        public virtual void Undo()
        {
        }
        public ElementOpreation ElementLink;
    }
    public class ElementOpreation
    {
        public List<IElement> LstElements { get; set; }

        public IPoint OffsetPt { get; set; }

    }

 步骤3.:然后具体的功能操作类去继承这个ElementUndoRedo类,去实现里面的undo和redo方法。

举例:当删除了Element后,然后想要使用undo来恢复这个Element


    class CmdDelteEle : ElementUndoRedo
    {

        private  IOperationStack pOperationStack=null;
        /// <summary>
        /// 删除元素
        /// </summary>
        public void MyExecute(IOperationStack poperationStack)
        {
            pOperationStack=poperationStack;
            IGraphicsContainer pGraphicsContainer = pPageLayoutControl.ActiveView.GraphicsContainer;
            pGraphicsContainer.Reset();
            IEnumElement pEnumElement = (pGraphicsContainer as IGraphicsContainerSelect).SelectedElements;
            IElement pElement = pEnumElement.Next();

            List<IElement> lstElement = new List<IElement>();
            while (pElement != null)
            {
                IElementProperties s = pElement as IElementProperties;

                pGraphicsContainer.DeleteElement(pElement);
                lstElement.Add(pElement);
                pElement = pEnumElement.Next();
            }

            ElementOpreation Eo = new ElementOpreation();
            Eo.LstElements = lstElement;
            this.ElementLink = Eo;


            pOperationStack.Do(this);//执行do方法

            (pGraphicsContainer as IActiveView).PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
        }

        public override void Undo()
        {
            IGraphicsContainer pGraphicsContainer = pPageLayoutControl.ActiveView.GraphicsContainer;
            CmdDelteEle cmdde = (pOperationStack.UndoOperation as CmdDelteEle);
            foreach (IElement pElement in cmdde.ElementLink.LstElements)
            {
                pGraphicsContainer.AddElement(pElement, 0);
            }
            pPageLayoutControl.ActiveView.Refresh();
        }


        public override void Redo()
        {
            IGraphicsContainer pGraphicsContainer = pPageLayoutControl.ActiveView.GraphicsContainer;
            CmdDelteEle cmdde = (CmdOpenMxd.pToolbar.OperationStack.RedoOperation as CmdDelteEle);

            foreach (IElement pElement in cmdde.ElementLink.LstElements)
            {
                pGraphicsContainer.DeleteElement(pElement);
            }
           pPageLayoutControl.ActiveView.Refresh();
        }
    }

调用:         

  if (pOperationStack.UndoOperation != null)
     {
        pToolbar.OperationStack.Undo();

     }

方法二:

    该方法是 使用AE提供的toobarcontrol控件,然后把AE自带的工具可以添加到toobarcontrol中,该控件有OperationStack属性,可以自动实现undo和redo,不需要编写具体的undo和redo代码就可以实现。另外我们可以把这个控件隐藏起来,然后把自定义的button上点击的时候去出发toobarcontrol的工具。这样就和整个项目界面风格统一起来。

                                                 

这里要注意的是要触发toobarcontrol中的工具的时候,需要从toolbarcontrol中获取这个工具。代码如下:

            axToolbarControl1.SetBuddyControl(axPageLayoutControl1.Object);
            IToolbarItem pToolbarItem = axToolbarControl1.GetItem(2);//获取selectElement的这个工具
            pTool = pToolbarItem.Command as ITool;
            axToolbarControl1.Hide();
            axPageLayoutControl1.CurrentTool = pTool;

然后在undo按钮和redo按钮中去写入如下代码即可:


        /// <summary>
        /// 撤销
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            IOperationStack operationStack = axToolbarControl1.OperationStack;
            try
            {
                if (operationStack.UndoOperation != null)
                {
                    operationStack.Undo();//调用AE自带重做指令
                }
                else
                {
                    MessageBox.Show("没有可撤消的操作!");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "无可撤消操作");
            }

        }

        private void button3_Click(object sender, EventArgs e)
        {
            IOperationStack operationStack = axToolbarControl1.OperationStack;
            try
            {
                if (operationStack.RedoOperation != null)
                {
                    operationStack.Redo();//调用AE自带重做指令
                }
                else
                {
                    MessageBox.Show("没有可撤消的操作!");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "无可撤消操作");
            }
        }

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值