最近在做一个功能,从主窗体弹出子窗体(包含地图控件)显示地图。不过初始化的过程比较耗时(主要是连接远程数据),所以想改变鼠标样式为等待。本来是比较简单的思路
A:主窗体,B:子窗体
a.cursor=cursors.wiatcursor;
B b=new B();
b.init();
a.cursor=cursors.arrow;
b.showdialog();
但是,发现运行过程中,鼠标就变成等待样式闪了一下,就变回去了。
经过排查,发现是B的构造函数里,初始化时控件容器加载了axmapcontrol造成的(但是pagelayout控件不影响,目前原理不明,有了解的朋友可以讲解下)。所以绕了个弯子,把axmapcontrol的初始化放到外面,等初始化参数完成后再进行初始化。
给B添了一个方法
public void addctrl()
{
this.controls.add(mapcontrol);//将设计器里的添加删除
mpcontrol.endinit();
}
A中恢复完鼠标样式后再调用下该方法。
其中endinit一定要调用,否则控件的属性和方法大都无法调用。因为axhost类继承ISupportInitialize接口,ISupportInitialize接口用于实现对对象进行批量初始化处理时的通知事务。调用BeginInit通知对象批量初始化开始,调用EndInit告诉对象批量初始化结束。使用这个接口的意义在于:对象内部某些属性可能具有相互依赖性,因此一些具有依赖性的处理需要在初始化完成之后才能进行。而ISupportInitialize正是为了实现这个功能而生,它的BeginInit方法的作用就是告诉对象当前正在初始化,从而不要去执行那些需要在初始化完成之后才能进行的操作。这里,我们使用ArcGIS engine的MapControl也存在这个问题,在AxMapControl没有被添加到控件容器中,即使调用了endinit,也被认为还没实例化,其内部的一些属性是拒绝访问的,如果使用,就出现System.Windows.Forms.AxHost+InvalidActiveXStateException异常。