麻辣GIS微信平台

更多 GIS 干货

微信关注不错过

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 开发手册

相关阅读

麻辣GIS-Sailor

作者:

GIS爱好者,学GIS,更爱玩GIS。

声明

1.本文所分享的所有需要用户下载使用的内容(包括但不限于软件、数据、图片)来自于网络或者麻辣GIS粉丝自行分享,版权归该下载资源的合法拥有者所有,如有侵权请第一时间联系本站删除。

2.下载内容仅限个人学习使用,请切勿用作商用等其他用途,否则后果自负。

手机阅读
公众号关注
知识星球
手机阅读
麻辣GIS微信公众号关注
最新GIS干货
关注麻辣GIS知识星球
私享圈子

留言板(小编看到第一时间回复)