ArcGIS Engine 10 开发手册(3-10)MapControl 控件与PageLayout控件的联动
视图控件PageLayoutControl
在 ArcMap 中除了在介绍 MapControl 控件的时候提到的数据视图,还有另外一种视图,就是布局视图 (Layout),PageLlayoutControl 控件则对应了 ArcMap 中的布局视图。PageLayoutControl 控件主要用于制图, 它可以方便的操作各种元素对象,以产生一副精美的地图对象出来。该控件中封装了一个 PageLayout 对象,这个对象用于控制布局视图中的对象的属性。
MapControl 控件与PageLayout控件的联动
要实现这两个控件的联动,我们首先回顾下 ArcMap 中的情景,两个控件的联动不仅仅是简单 的切换,在切换的时候还因该保留各自控件上的一些状态,比如说当我们在 MapControl 上有一个放大操作 时,当我们没有将这个放大操作取消而切换到 PageLayout 控件,在 PageLayout 控件上做了一些操作后,又 切换到 MapControl 控件,我们应该还应该能进行放大操作而不用重新使用放大这个工具。
通过分析我们可以得到下面几点:
- 当切换两个控件的时候,地图的同步
- 各自控件上激活的工具或者命令的保留
- 当存在 TOC 控件和 ToolBar 控件的时候,切换了地图控件和布局控件,那么这两个控件的伙伴控 件也应发生变化。
在 Form 中添加 TabControl 控件,分别将地图控件和布局控件放置到里面,如下图所示:
我们在 NET 中定义一个类,这个类用来实现这两个功能,类的名称是 ControlsSynchronizer
/// 在构造函数中传入地图控件和布局控件
public ControlsSynchronizer (IMapControl3_MapControl, IPageLayoutControl2 _PageLayoutControl): this ()
{
//assign the class members pMapControl = _MapControl;
pPageLayoutControl = \_PageLayoutControl;
}
/// 激活地图控件并销毁布局控件
public void ActivateMap ()
{
try
{
if (pPageLayoutControl == null || pMapControl == null)
throw new Exception ("ControlsSynchronizer::ActivateMap:\\r\\nEither MapControl or PageLayoutControl are not initialized!");
//cache the current tool of the PageLayoutControl
if (pPageLayoutControl.CurrentTool != null) pPageLayoutActiveTool = pPageLayoutControl.CurrentTool;
//销毁PagleLayout
pPageLayoutControl.ActiveView.Deactivate();
//激活 MapControl
pMapControl.ActiveView.Activate(pMapControl.hWnd);
//将保留下来的工具付给MapControl
if (pMapActiveTool != null) pMapControl.CurrentTool = pMapActiveTool;
pIsMapControlactive = true;
//on each of the framework controls, set the Buddy control to the MapControl this.SetBuddies
(pMapControl.Object);
} catch (Exception ex)
{
throw new Exception (string.Format ("ControlsSynchronizer::ActivateMap:\\r\\n{0}",
ex.Message));
}
}
/// 激活布局控件并销毁地图控件
public void ActivatePageLayout ()
{
try
{
if (pPageLayoutControl == null || pMapControl == null)
throw new Exception ("ControlsSynchronizer::ActivatePageLayout:\\r\\nEither MapControl or PageLayoutControl are not initialized!");
//cache the current tool of the MapControl
if (pMapControl.CurrentTool != null) pMapActiveTool = pMapControl.CurrentTool;
//销毁 MapControl
pMapControl.ActiveView.Deactivate();
//激活 PageLayoutControl
pPageLayoutControl.ActiveView.Activate(pPageLayoutControl.hWnd);
//将保留下来的工具付给PageLayoutControl
if (pPageLayoutActiveTool != null) pPageLayoutControl.CurrentTool = pPageLayoutActiveTool;
pIsMapControlactive = false;
//on each of the framework controls , set the Buddy control to the PageLayoutControl
this.SetBuddies (pPageLayoutControl.Object);
} catch (Exception ex)
{
throw new Exception (string.Format ("ControlsSynchronizer::ActivatePageLayout:\r\n{0}",ex.Message));
}
}
/// 当激活的控件发生变化时,IToolbarControl控件和ITOCControl控件的伙伴控件也应发生变化
private void SetBuddies(object _buddy)
{
try
{
if (_buddy == null)
throw new Exception ("ControlsSynchronizer::SetBuddies:\r\nTarget Buddy Control is not initialized!");
foreach (object obj in pFrameworkControls)
{
if (obj is IToolbarControl)
{
((IToolbarControl) obj).SetBuddyControl (_buddy);
} else if (obj is ITOCControl)
{
((ITOCControl) obj).SetBuddyControl (_buddy);
}
}
} catch (Exception ex)
{
throw new Exception (string.Format ("ControlsSynchronizer::SetBuddies:\r\n{0}",ex.Message));
}
}
/// 如果地图发生了变化,那么地图控件和布局控件的地图也应发生变化
public void ReplaceMap(IMap _NewMap)
{
if (_NewMap == null)
throw new Exception ("ControlsSynchronizer::ReplaceMap:\\r\\nNew map for replacement is not initialized!");
if (pPageLayoutControl == null || pMapControl == null)
throw new Exception ("ControlsSynchronizer::ReplaceMap:\\r\\nEither MapControl or PageLayoutControl are not initialized!");
//create a new instance of IMaps collection which is needed by the PageLayout
IMaps pMaps = new Maps();
//添加新的地图
pMaps.Add(_NewMap);
bool bIsMapActive = pIsMapControlactive;
//call replace map on the PageLayout in order to replace the focus map
//we must call ActivatePageLayout, since it is the control we call 'ReplaceMaps'
this.ActivatePageLayout();
pPageLayoutControl.PageLayout.ReplaceMaps (pMaps);
//assign the new map to the MapControl
pMapControl.Map = _NewMap;
//reset the active tools
pPageLayoutActiveTool = null;
pMapActiveTool = null;
//make sure that the last active control is activated
if (bIsMapActive)
{
this.ActivateMap ();
pMapControl.ActiveView.Refresh ();
} else
{
this.ActivatePageLayout ();
pPageLayoutControl.ActiveView.Refresh ();
}
}
/// 当运行应用程序的时候,即便没有加载地图,则创建一个空的地图,让这两个控件和这 个地图绑定在一起,这样就能保持一致
public void BindControls (bool_ActivateMapFirst)
{
if (pPageLayoutControl == null || pMapControl == null)
throw new Exception ("ControlsSynchronizer::BindControls:\\r\\nEither MapControl or PageLayoutControl are not initialized!");
//创建一个地图实例
IMap pNewMap = new MapClass ();
pNewMap.Name = "Map";
//其中Maps为我们创建的一个类,表示的是地图的集合 IMaps
pMaps = new Maps();
//add the new Map instance to the Maps collection
pMaps.Add(pNewMap);
//call replace map on the PageLayout in order to replace the focus map
pPageLayoutControl.PageLayout.ReplaceMaps(pMaps);
//assign the new map to the MapControl
pMapControl.Map = pNewMap;
//reset the active tools
pPageLayoutActiveTool = null;
pMapActiveTool = null;
//make sure that the last active control is activated
if (_ActivateMapFirst)
this.ActivateMap ();
else
this.ActivatePageLayout ();
}
还记得我们上次创建的那个打开地图文档的命令? 在打开地图的时候, 我们只不过是将这个地图付给 了 Map 控件, 这样的话布局控件是得不到图的, 因此应该对 OnClick 改动下, 在这个里面将 map 控件和布 局控件同步起来
public override void OnClick ()
{
//launch a new OpenFile dialog
OpenFileDialog dlg = new OpenFileDialog();
dlg.Filter = "Map Documents (*.mxd)|*.mxd"; dlg.Multiselect = false;
dlg.Title = "Open Map Document";
if (dlg.ShowDialog () == DialogResult.OK)
{
string docName = dlg.FileName;
IMapDocument pMapDoc = new MapDocumentClass ();
if (pMapDoc.get_IsPresent (docName) &&!pMapDoc.get_IsPasswordProtected (docName))
{
pMapDoc.Open (docName, string.Empty);
// set the first map as the active view
IMap map = pMapDoc.get\_Map(0); pMapDoc.SetActiveView((IActiveView)map);
pControlsSynchronizer.PageLayoutControl.PageLayout = pMapDoc.PageLayout;
pControlsSynchronizer.ReplaceMap (map);
pMapDoc.Close ();
m_sDocumentPath = docName;
}
}
}
在ControlsSynchronizer类中使用的Maps类的代码如下:
namespace EngineApplication
{
/// Implementation of interface IMaps which is eventually a collection of Maps
public class Maps : IMaps, IDisposable
{
//class member - using internally an ArrayList to manage the Maps collection
private ArrayList pArray = null;
#region class constructor public Maps ()
{
pArray = new ArrayList ();
}
#endregion
#region IDisposable Members
/// Dispose the collection
public void Dispose ()
{
if (pArray != null)
{
pArray.Clear ();
pArray = null;
}
}
#endregion
#region IMaps Members
/// Remove the Map at the given index
public void RemoveAt(int Index)
{
if (Index & gt; pArray.Count || Index & lt; 0)
throw new Exception ("Maps::RemoveAt:\r\nIndex is out of range!");
pArray.RemoveAt (Index);
}
/// Reset the Maps array
public void Reset()
{
pArray.Clear ();
}
/// Get the number of Maps in the collection
public int Count
{
get
{
return pArray.Count;
}
}
public IMap get_Item (int Index)
{
if (Index & gt; pArray.Count || Index & lt; 0)
throw new Exception ("Maps::get_Item:\r\nIndex is out of range!");
return pArray[Index] as IMap;
}
/// Remove the instance of the given Map
public void Remove(IMap Map)
{
pArray.Remove (Map);
}
/// Create a new Map, add it to the collection and return it to the caller
public IMap Create ()
{
IMap newMap = new MapClass ();
pArray.Add (newMap);
return newMap;
}
/// Add the given Map to the collection
public void Add(IMap Map)
{
if (Map == null)
throw new Exception ("Maps::Add:\\r\\nNew Map is mot initialized!");
pArray.Add (Map);
}
#endregion
}
}
ArcGIS Engine 10 开发手册全集
ArcGIS Engine 10 开发手册全集: ArcGIS Engine 10 开发手册
相关阅读
声明
1.本文所分享的所有需要用户下载使用的内容(包括但不限于软件、数据、图片)来自于网络或者麻辣GIS粉丝自行分享,版权归该下载资源的合法拥有者所有,如有侵权请第一时间联系本站删除。
2.下载内容仅限个人学习使用,请切勿用作商用等其他用途,否则后果自负。