『公告』 预祝您龙年大吉,万事如意, 过节期间, 大家如需数据服务,请拨打400 或直接添加客服微信,再祝大家龙年,心想事成。
关注我们 新浪 腾讯

ArcGIS Engine 10 开发手册(3-10)MapControl 控件与PageLayout控件的联动

ArcGIS Engine 10 开发手册(3-10)MapControl 控件与PageLayout控件的联动
在 ArcMap 中除了在介绍 MapControl 控件的时候提到的数据视图,还有另外一种视图。

     视图控件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

  }

}

 

 


      京ICP备2025132830号-1 京公网安备 号