点击源码下载
效果图:
在制图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(), "无可撤消操作");
}
}