文件夹的图标。
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的属性中将其删除。 下面,我们可完成上一讲遗留的功能了。 ///
/// 新建地图命令 ///
///
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(); }
//创建新的地图实例
IMap map = new MapClass(); map.Name = \
m_controlsSynchronizer.MapControl.DocumentFilename = string.Empty; //更新新建地图实例的共享地图文档
m_controlsSynchronizer.ReplaceMap(map); }
///
/// 打开地图文档Mxd命令 ///
///
private void Open_Click(object sender, EventArgs e) {
if (this.axMapControl1.LayerCount > 0) {
DialogResult result = MessageBox.Show(\是否保存当前地图?\警告\MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); if (result == DialogResult.Cancel) return;
if (result == DialogResult.Yes) this.Save_Click(null, null); }
OpenNewMapDocument openMapDoc = new OpenNewMapDocument(m_controlsSynchronizer);
openMapDoc.OnCreate(m_controlsSynchronizer.MapControl.Object); openMapDoc.OnClick(); }
在添加数据AddData时,我们也要进行地图共享,故在AddData_Click函数后面添加如下代码:
IMap pMap = this.axMapControl1.Map;
this.m_controlsSynchronizer.ReplaceMap(pMap);
在另存为地图文档时,有可能会丢失数据,因此我们需要提示用户以确认操作,故需修改SaveAs_Click函数,如下所示:
///
/// 另存为地图文档命令 ///
///
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; }
//调用另存为命令
ICommand command = new ControlsSaveAsDocCommandClass(); command.OnCreate(m_controlsSynchronizer.ActiveControl); command.OnClick(); }
在切换视图时,我们要激活相关的视图,故在设计视图的属性面板中选择tabControl2控件,再选择事件按钮,找到“SelectedIndexChanged”事件双击添加之。其实现代码如下所示: ///
/// 切换地图和制版视图 ///
///
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两种视图的同步工作。
第四讲 状态栏信息的添加与实现
在上一讲中,我们完成了 MapControl 和 PageLayoutControl 两种视图的同步工作,本讲我们将完成状态栏信息的添加与实现。
应用程序的状态栏一般用来显示程序的当前状态,当前所使用的工具。 GIS 应用程序一般也在状态栏显示当前光标的坐标、比例尺等信息。
学习完本讲内容,您将学会状态栏编程的基本方法,并且能够在我们的程序的状态栏中添加且显示以下信息: 当前所用工具信息 当前比例尺 当前坐标
1、 添加状态栏项目
在设计视图中,点击窗体中的状态栏,在其属性面板中找到“ Items ”项,单击其右边的按钮,在下拉框中选择“ StatusLabel ”,单击“添加按钮”,依次添加四个 StatusLabel ,依次修改属性参数如下表所示:
设置好之后如下所示:
Tips : 我们
设
计
出
的
状
态
栏
最
终
如
下
所
示
:
Spring 属性表示可以按状态栏剩余空间自动伸缩。所以加入 Blank 项目,只是为了占个位子,以达到 ScaleLabel 和 CoordinateLabel 项目右对齐而 MessageLabel 项目左对齐的目的。
2、 显示当前所用工具信息
首先添加 axToolbarControl1 的 OnMouseMove 事件 ( 相信大家看了以上的教程,已经知道怎么添加事件了吧,还不知道的建议再温习下前几讲的内容 ) 。在其事件响应函数代码如下: private void axToolbarControl1_OnMouseMove(object sender, IToolbarControlEvents_OnMouseMoveEvent e) {
// 取得鼠标所在工具的索引号
int index = axToolbarControl1.HitTest(e.x, e.y, false); if (index != -1) {
// 取得鼠标所在工具的 ToolbarItem
IToolbarItem toolbarItem = axToolbarControl1.GetItem(index); // 设置状态栏信息
MessageLabel.Text = toolbarItem.Command.Message; } else {
MessageLabel.Text = \就绪 \} }
3、 显示当前比例尺
添加 axMapControl1 的 OnMouseMove 事件,其代码如下:
private void axMapControl1_OnMouseMove(object sender, IMapControlEvents2_OnMouseMoveEvent e) {
// 显示当前比例尺
ScaleLabel.Text = \比例尺 1:\}
4、 显示当前坐标
显示当前坐标也是 axMapControl1 的 OnMouseMove 事件中响应,故只要在 axMapControl1_OnMouseMove 函数中添加如下代码即可: // 显示当前坐标
CoordinateLabel.Text=\当前坐标X =\\this.axMapControl1.MapUnits;
按 F5 编译运行,可以看到,我们的程序已经能够正常工作了。但是细心的你可能会发现,当前坐标的后面的坐标单位为“ esriUnknownUnits ”或“ esriMeters ”之类,即系统在正常单位的前面加上了“ esri ”,追求完美的我们自然看得不舒服。那就进行简单的替换吧。 首先定义个全局坐标单位变量 sMapUnits ,如下所示:
private string sMapUnits;
//再 Form1_Load 函数中进行初始化: sMapUnits = \
添加 axMapControl1 控件的 OnMapReplaced 事件,在事件响应函数中进行坐标单位替换,代码如下:
private void axMapControl1_OnMapReplaced(object sender, IMapControlEvents2_OnMapReplacedEvent e) {
esriUnits mapUnits = axMapControl1.MapUnits; switch (mapUnits) {
case esriUnits.esriCentimeters: sMapUnits = \break;
case esriUnits.esriDecimalDegrees: sMapUnits = \break;
case esriUnits.esriDecimeters: sMapUnits = \break;
case esriUnits.esriFeet: sMapUnits = \break;
case esriUnits.esriInches: sMapUnits = \break;
case esriUnits.esriKilometers: sMapUnits = \break;
case esriUnits.esriMeters: sMapUnits = \break;
case esriUnits.esriMiles: sMapUnits = \break;
case esriUnits.esriMillimeters: sMapUnits = \break;
case esriUnits.esriNauticalMiles: sMapUnits = \break;
case esriUnits.esriPoints: sMapUnits = \break;
case esriUnits.esriUnknownUnits: sMapUnits = \break;
case esriUnits.esriYards: sMapUnits = \break; } }
5、 编译运行
按 F5 编译运行程序。如果你足够细心的话,相信你已经成功了! 在本讲中,介绍中 StatusStrip 控件的基本使用方法和 AE 中当所用工具信息、当前比例尺和当前坐标的显示调用方法。
第五讲 鹰眼的实现
在上一讲中,我们实现了状态栏的相关信息显示,在这一讲中我们将要实现鹰眼功能。
所谓的鹰眼,就是一个缩略地图,上面有一个矩形框,矩形框区域就是当前显示的地图区域,拖动矩形框可以改变当前地图显示的位置,改变矩形框的大小,可以改变当前地图的显示区域大小,从起到导航的作用。鹰眼是地图浏览中常用的功能之一。
关于鹰眼的实现方式,最常用的是用一个 MapControl 控件显示地图全图,并在上面画一个红色矩形框表示当前地图的显示范围,并实现鹰眼 MapControl 与主窗体的 MapControl 互动。本讲最终效果如下所示: