《ArcGIS Engine+C#实例开发教程》第三讲 MapControl与PageLayoutControl同步
原文:《ArcGIS Engine+C#实例开发教程》第三讲 MapControl与PageLayoutControl同步
教程目录:
第三讲 MapControl与PageLayoutControl同步
------------------------------------------------------------------
在ArcMap中,能够很方面地进行MapView和Layout View两种视图的切换,而且二者之间的数据是同步显示的。
关于两种视图同步的实现方法有多种,可以使用ObjectCopy对象进行数据硬拷贝,而比较简单的方法莫过于二者共享一份地图了,这也是最常用的方法。
1、新建同步类ControlsSynchronizer
在解决方案面板中右击项目名,选择“添加|类”,在类别中选择“Visual C#项目项”,在模板中选择“类”,输入类名“ControlsSynchronizer.cs”,将以下代码覆盖自动生成的代码:
| using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.IO; using System.Runtime.InteropServices; using ESRI.ArcGIS.esriSystem; namespace _sdnMap private ArrayList m_frameworkControls = null; #region constructor /// <summary> /// <summary> #region properties /// <summary> /// <summary> /// <summary> if (m_IsMapCtrlactive) #region Methods //缓存当前PageLayout的CurrentTool //解除PagleLayout //激活MapControl //将之前MapControl最后使用的tool,作为活动的tool,赋给MapControl的CurrentTool m_IsMapCtrlactive = true; //为每一个的framework controls,设置Buddy control为MapControl /// <summary> //缓存当前MapControl的CurrentTool //解除MapControl //激活PageLayoutControl //将之前PageLayoutControl最后使用的tool,作为活动的tool,赋给PageLayoutControl的CurrentTool m_IsMapCtrlactive = false; //为每一个的framework controls,设置Buddy control为PageLayoutControl /// <summary> if (m_pageLayoutControl == null || m_mapControl == null) //create a new instance of IMaps collection which is needed by the PageLayout bool bIsMapActive = m_IsMapCtrlactive; //call replace map on the PageLayout in order to replace the focus map //assign the new map to the MapControl //reset the active tools //make sure that the last active control is activated /// <summary> m_mapControl = MapControl; this.BindControls(activateMapFirst); /// <summary> //create a new instance of IMap //create a new instance of IMaps collection which is needed by the PageLayout //call replace map on the PageLayout in order to replace the focus map //reset the active tools //make sure that the last active control is activated /// <summary> m_frameworkControls.Add(control); /// <summary> m_frameworkControls.Remove(control); /// <summary> m_frameworkControls.RemoveAt(index); /// <summary> foreach (object obj in m_frameworkControls) |
2、新建Maps类
在同步类中,要用到Maps类,用于管理地图对象。与新建同步类ControlsSynchronizer类似,我们新建一Maps类,其所有代码如下所示:
|
using System; using ESRI.ArcGIS.Carto; namespace _sdnMap #region class constructor #region IDisposable Members /// <summary> #endregion #region IMaps Members /// <summary> m_array.RemoveAt(Index); /// <summary> /// <summary> /// <summary> return m_array[Index] as IMap; /// <summary> /// <summary> return newMap; /// <summary> m_array.Add(Map); #endregion |
3、新建打开文档类OpenNewMapDocument
由于从工具栏自带的打开按钮打开地图文档的时候,不会自动进行两种视图之间的同步,所以我们要自己派生一个OpenNewMapDocument类,用于打开地图文档。
右击项目名,选择“添加|类”,再选择ArcGIS类别中的BaseCommand模板,输入类名为“OpenNewMapDocument.cs”。
首先添加引用:
| using System.Windows.Forms; using ESRI.ArcGIS.Carto; |
再添加如下成员变量:
| private ControlsSynchronizer m_controlsSynchronizer = null; |
修改默认的构造函数如下所示:
| //添加参数 public OpenNewMapDocument(ControlsSynchronizer controlsSynchronizer) { // // TODO: Define values for the public properties // //设定相关属性值 base.m_category = "Generic"; //localizable text base.m_caption = "Open"; //localizable text base.m_message = "This should work in ArcMap/MapControl/PageLayoutControl"; //localizable text base.m_toolTip = "Open"; //localizable text base.m_name = "Generic_Open"; //unique id, non-localizable (e.g. "MyCategory_MyCommand") //初始化m_controlsSynchronizer m_controlsSynchronizer = controlsSynchronizer; try |
再在OnClick函数中添加如下代码:
| public override void OnClick() { // TODO: Add OpenNewMapDocument.OnClick implementation 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 mapDoc = new MapDocumentClass(); mapDoc.Close(); |
在添加类时,模板会自动添加一个名为“OpenNewMapDocument.bmp”的图标,你可以自己修改或者替换为打开的文件夹的图标。
4、两种视图的同步
在3sdnMap.cs中添加成员变量,即同步类对象:
| private ControlsSynchronizer m_controlsSynchronizer = null; |
在Form1_Load函数中进行初始化工作:
| //初始化controls synchronization calss m_controlsSynchronizer = new ControlsSynchronizer(m_mapControl, m_pageLayoutControl); //把MapControl和PageLayoutControl绑定起来(两个都指向同一个Map),然后设置MapControl为活动的Control m_controlsSynchronizer.BindControls(true); //为了在切换MapControl和PageLayoutControl视图同步,要添加Framework Control m_controlsSynchronizer.AddFrameworkControl(axToolbarControl1.Object); m_controlsSynchronizer.AddFrameworkControl(this.axTOCControl1.Object); // 添加打开命令按钮到工具条 OpenNewMapDocument openMapDoc = new OpenNewMapDocument(m_controlsSynchronizer); axToolbarControl1.AddItem(openMapDoc, -1, 0, false, -1, esriCommandStyles.esriCommandStyleIconOnly); |
因为我们自动派生了打开文档类,并自己将其添加到工具条,所以我们就不需要工具条原来的“打开”按钮了,可以ToolbarControl的属性中将其删除。
下面,我们可完成上一讲遗留的功能了。
| /// <summary> /// 新建地图命令 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void New_Click(object sender, EventArgs e) { //询问是否保存当前地图 DialogResult res = MessageBox.Show("是否保存当前地图?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (res == DialogResult.Yes) { //如果要保存,调用另存为对话框 ICommand command = new ControlsSaveAsDocCommandClass(); if (m_mapControl != null) command.OnCreate(m_controlsSynchronizer.MapControl.Object); else command.OnCreate(m_controlsSynchronizer.PageLayoutControl.Object); command.OnClick(); |
|
/// <summary> |
在添加数据AddData时,我们也要进行地图共享,故在AddData_Click函数后面添加如下代码:
| IMap pMap = this.axMapControl1.Map; this.m_controlsSynchronizer.ReplaceMap(pMap); |
在另存为地图文档时,有可能会丢失数据,因此我们需要提示用户以确认操作,故需修改SaveAs_Click函数,如下所示:
| /// <summary> /// 另存为地图文档命令 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void SaveAs_Click(object sender, EventArgs e) { //如果当前视图为MapControl时,提示用户另存为操作将丢失PageLayoutControl中的设置 if (m_controlsSynchronizer.ActiveControl is IMapControl3) { if (MessageBox.Show("另存为地图文档将丢失制版视图的设置\r\n您要继续吗?", "提示",MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) return; } //调用另存为命令 |
在切换视图时,我们要激活相关的视图,故在设计视图的属性面板中选择tabControl2控件,再选择事件按钮,找到“SelectedIndexChanged”事件双击添加之。其实现代码如下所示:
| /// <summary> /// 切换地图和制版视图 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void tabControl2_SelectedIndexChanged(object sender, EventArgs e) { if (this.tabControl2.SelectedIndex == 0) { //激活MapControl m_controlsSynchronizer.ActivateMap(); } else { //激活PageLayoutControl m_controlsSynchronizer.ActivatePageLayout(); } } |
5、编译运行
按F5编译运行程序,至此我们完成了MapControl和PageLayoutControl两种视图的同步工作。
《ArcGIS Engine+C#实例开发教程》第三讲 MapControl与PageLayoutControl同步的更多相关文章
- 《ArcGIS Engine+C#实例开发教程》第七讲 图层符号选择器的实现2
原文:<ArcGIS Engine+C#实例开发教程>第七讲 图层符号选择器的实现2 摘要:在第七讲 图层符号选择器的实现的第一阶段中,我们完成了符号选择器窗体的创建与调用.在第二阶段中, ...
- 《ArcGIS Engine+C#实例开发教程》第八讲 属性数据表的查询显示
原文:<ArcGIS Engine+C#实例开发教程>第八讲 属性数据表的查询显示 第一讲 桌面GIS应用程序框架的建立 第二讲 菜单的添加及其实现 第三讲 MapControl与Page ...
- 《ArcGIS Engine+C#实例开发教程》第六讲 右键菜单添加与实现
原文:<ArcGIS Engine+C#实例开发教程>第六讲 右键菜单添加与实现 摘要:在这一讲中,大家将实现TOCControl控件和主地图控件的右键菜单.在AE开发中,右键菜单有两种实 ...
- 《ArcGIS Engine+C#实例开发教程》第四讲 状态栏信息的添加与实现
原文:<ArcGIS Engine+C#实例开发教程>第四讲 状态栏信息的添加与实现 摘要:在上一讲中,我们完成了 MapControl 和PageLayoutControl两种视图的同步 ...
- 《ArcGIS Engine+C#实例开发教程》第五讲 鹰眼的实现
原文:<ArcGIS Engine+C#实例开发教程>第五讲 鹰眼的实现 摘要:所谓的鹰眼,就是一个缩略地图,上面有一个矩形框,矩形框区域就是当前显示的地图区域,拖动矩形框可以改变当前地图 ...
- 《ArcGIS Engine+C#实例开发教程》第二讲 菜单的添加及其实现
原文:<ArcGIS Engine+C#实例开发教程>第二讲 菜单的添加及其实现 摘要:在上一讲中,我们实现了应用程序基本框架,其中有个小错误,在此先跟大家说明下.在“属性”选项卡中,我们 ...
- 《ArcGIS Engine+C#实例开发教程》
原文:<ArcGIS Engine+C#实例开发教程> 摘要:<ArcGIS Engine+C#实例开发教程>,面向 ArcGIS Engine(以下简称AE)开发初学者,本教 ...
- 《ArcGIS Engine+C#实例开发教程》第一讲桌面GIS应用程序框架的建立
原文:<ArcGIS Engine+C#实例开发教程>第一讲桌面GIS应用程序框架的建立 摘要:本讲主要是使用MapControl.PageLayoutControl.ToolbarCon ...
- ArcGIS Runtime for Android开发教程V2.0(1)基本概念
原文地址: ArcGIS Runtime for Android开发教程V2.0(1)基本概念 - ArcGIS_Mobile的专栏 - 博客频道 - CSDN.NET http://blog.csd ...
随机推荐
- Mysql - 解决Access denied for user ''@'localhost' to database 'mysql'问题
http://361324767.blog.163.com/blog/static/11490252520124454042468/ 首先我想说一句话: 我极度鄙视国内搞IT的人,简直无语,同样是解决 ...
- java String的equals,intern方法(转载)
JAVA中的equals和==的区别 ==比较的是2个对象的地址,而equals比较的是2个对象的内容. 显然,当equals为true时,==不一定为true: 基础知识的重要性,希望引起大家的重视 ...
- ios -- cell的图片下载
1.面试题 1> 如何防止一个url对应的图片重复下载 * “cell下载图片思路 – 有沙盒缓存” 2> SDWebImage的默认缓存时长是多少? * 1个星期 3> SDWeb ...
- html-----020----事件
html事件 <body> <a href="http://www.cctv.com" accesskey="k" target=" ...
- css 盒子模型理解
盒子模型是html+css中最核心的基础知识,理解了这个重要的概念才能更好的排版,进行页面布局.下面是自己积累和总结的关于css盒子模型的知识^_^,希望对初学者有用. 一.css盒子模型概念 CSS ...
- sublime text 使用
一.在sublime text中创建html.css.js文件 ctrl+shift+p(调出控制台) 然后输入 Set Syntax:html(也可以输入:ssh) Set Syntax:css ...
- hdu 1047 Integer Inquiry(高精度数)
Problem Description Oneof the first users of BIT's new supercomputer was Chip Diller. He extended hi ...
- 第36条:坚持使用Override注解
@Override 注解只能用在方法声明中,表示被注解的方法声明覆盖了超类型中的一个声明. @Target(ElementType.METHOD) @Retention(RetentionPolicy ...
- Linux内核中的通用双向循环链表
开发中接触Linux越来越多,休息放松之余,免不了翻看翻看神秘的Linux的内核.看到双向链表时,觉得挺有意思的,此文记下. 作为众多基础数据结构中的一员,双向循环链表在各种“教科书”中的实现是相当的 ...
- oracle11g 表或视图连接时有可能发生的问题
---------背景--------- oracle11g 有2个视图,都有一个id字段,且id字段的值相同 例如:id都有 A01 ,A02 ,A03 --------问题--------- 把2 ...