原文 http://blog.csdn.net/flexmapserver/article/details/5868882

用Windows Form进行ArcGIS Engine二次开发时常见的形式,当然也可以用WPF来进行ArcEngine的二次开发。

由于WPF很方便承载Windows Form控件,而Map Control、Toolbar Control、TOC Control等都是.NET 控件,当然也可以用XAML来承载ArcEngine的这些控件来开发了。

下面简单记述开发步骤:

1.打开VS2008,创建WPF应用程序;

2.添加程序集引用:

  • ESRI.ArcGIS.AxControls:包含地图控件
  • ESRI.ArcGIS.System:包含ArcGIS Engine license初始化类
  • WindowsFormsIntegration:包含WindowsFormsHost,用来在WPF中承载Windows控件
  • System.Windows.Forms

3.在XAML中添加名称空间:

xmlns:controlHost="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"

添加初始化事件Loaded="Window_Loaded"

4.在XAML中添加Map Control、Toolbar Control、TOC Control控件,最后你的XAML代码看起来是这样:

  1. <Window x:Class="WPFMapViewer.MapWindow"
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4. Title="MapViewer Hosted in WPF" Height="433.29" Width="559.944" Loaded="Window_Loaded" Background="Beige"
  5. MaxHeight="768" MaxWidth="1024"
  6. xmlns:my="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration">
  7. <Grid>
  8. <my:WindowsFormsHost Name="mapHost" Margin="174,30,0,22" />
  9. <my:WindowsFormsHost Margin="0,30,0,22" Name="tocHost" HorizontalAlignment="Left" Width="173" />
  10. <my:WindowsFormsHost Height="30" Name="toolbarHost" VerticalAlignment="Top" Margin="0,0,252,0" />
  11. <Button Content="MyZoomInBoxTool" x:Name="MyZoomInBoxTool" Click="MyZoomInBox_Click" HorizontalAlignment="Right" Width="120" Height="30" VerticalAlignment="Top" Panel.ZIndex="1" Margin="0,0,7.056,0"></Button>
  12. <TextBlock Height="23.75" VerticalAlignment="Bottom" Name="textBlock1" Margin="0,0,7.056,0">Ready</TextBlock>
  13. <Button x:Name="DrawCircleTool" Height="23" HorizontalAlignment="Right" Margin="0,5,153,0" VerticalAlignment="Top" Width="75" Click="DrawCircleTool_Click">DrawCircle</Button>
  14. </Grid>
  15. </Window>

5.编辑XAML的C#代码,添加Map Control、Toolbar Control、TOC Control三个变量,即

AxMapControl mapControl;
             AxToolbarControl toolbarControl;
             AxTOCControl tocControl;

并在初始化窗口的下面添加对这三个控件变量的创建,即

  1. private void CreateEngineControls ()
  2. {
  3. mapControl = new AxMapControl ();
  4. mapHost.Child = mapControl;
  5. toolbarControl = new AxToolbarControl ();
  6. toolbarHost.Child = toolbarControl;
  7. tocControl = new AxTOCControl ();
  8. tocHost.Child = tocControl;
  9. }

6.在Window_Loaded事件中加载上述三个控件,如下:

  1. private void LoadMap ()
  2. {
  3. //将TOC控件、Toolbar控件和地图控件绑定
  4. tocControl.SetBuddyControl (mapControl);
  5. toolbarControl.SetBuddyControl (mapControl);
  6. //添加放大、缩小、打开地图文档等命令到Toolbar工具栏
  7. toolbarControl.AddItem ("esriControls.ControlsOpenDocCommand");
  8. toolbarControl.AddItem ("esriControls.ControlsAddDataCommand");
  9. toolbarControl.AddItem ("esriControls.ControlsSaveAsDocCommand");
  10. toolbarControl.AddItem ("esriControls.ControlsMapNavigationToolbar");
  11. toolbarControl.AddItem ("esriControls.ControlsMapIdentifyTool");
  12. //设置工具栏的外观
  13. toolbarControl.BackColor =Color.FromArgb (245, 245, 220);
  14. }

7.将上述代码连起来,你的代码看起来是这样:

  1. public partial class MapWindow: Window
  2. {
  3. AxMapControl mapControl;
  4. AxToolbarControl toolbarControl;
  5. AxTOCControl tocControl;
  6. public MapWindow ()
  7. {
  8. InitializeComponent ();
  9. CreateEngineControls ();
  10. }
  11. private void CreateEngineControls ()
  12. {
  13. mapControl = new AxMapControl ();
  14. mapHost.Child = mapControl;
  15. toolbarControl = new AxToolbarControl ();
  16. toolbarHost.Child = toolbarControl;
  17. tocControl = new AxTOCControl ();
  18. tocHost.Child = tocControl;
  19. }
  20. private void LoadMap ()
  21. {
  22. //将TOC控件、Toolbar控件和地图控件绑定
  23. tocControl.SetBuddyControl (mapControl);
  24. toolbarControl.SetBuddyControl (mapControl);
  25. //添加放大、缩小、打开地图文档等命令到Toolbar工具栏
  26. toolbarControl.AddItem ("esriControls.ControlsOpenDocCommand");
  27. toolbarControl.AddItem ("esriControls.ControlsAddDataCommand");
  28. toolbarControl.AddItem ("esriControls.ControlsSaveAsDocCommand");
  29. toolbarControl.AddItem ("esriControls.ControlsMapNavigationToolbar");
  30. toolbarControl.AddItem ("esriControls.ControlsMapIdentifyTool");
  31. //设置工具栏的外观
  32. toolbarControl.BackColor =Color.FromArgb (245, 245, 220);
  33. }
  34. private void Window_Loaded (object sender, RoutedEventArgs e)
  35. {
  36. LoadMap ();
  37. }
  38. }

8.ArcEngine的二次开发当然要License啦,在Windwos From的开发中可以用License控件来进行许可证的初始化,在这里就只能用代码在App.XAML.cs中初始化License了。

代码如下:

  1. public partial class App: Application
  2. {
  3. public App ()
  4. {
  5. InitializeEngineLicense ();
  6. }
  7. private void InitializeEngineLicense ()
  8. {
  9. AoInitialize aoi = new AoInitializeClass ();
  10. esriLicenseProductCode productCode = esriLicenseProductCode.esriLicenseProductCodeEngine;
  11. if (aoi.IsProductCodeAvailable (productCode) == esriLicenseStatus.esriLicenseAvailable)
  12. {
  13. aoi.Initialize (productCode);
  14. }
  15. }
  16. }

9.在WPF中添加自定义工具,如在视图上画圆形的工具,添加DrawCircleToolClass类,如下:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Runtime.InteropServices;
  6. using ESRI.ArcGIS.ADF.CATIDs;
  7. using ESRI.ArcGIS.Controls;
  8. using ESRI.ArcGIS.Geometry;
  9. using ESRI.ArcGIS.Display;
  10. using ESRI.ArcGIS.Carto;
  11. using ESRI.ArcGIS.ADF.BaseClasses;
  12. namespace WPFMapViewer.MapTool
  13. {
  14. [ClassInterface(ClassInterfaceType.None)]
  15. [Guid("48BD64CD-3369-47FC-8EC5-94A5B644E8DA")]
  16. public class DrawCircleToolClass : BaseTool
  17. {
  18. [ComRegisterFunction()]
  19. [ComVisible(false)]
  20. static void RegisterFunction(Type registerType)
  21. {
  22. ArcGISCategoryRegistration(registerType);
  23. }
  24. [ComUnregisterFunction()]
  25. [ComVisible(false)]
  26. static void UnregisterFunction(Type registerType)
  27. {
  28. ArcGISCategoryUnregistration(registerType);
  29. }
  30. private static void ArcGISCategoryRegistration(Type registerType)
  31. {
  32. string regKey = string.Format("HKEY_CLASSES_ROOT//CLSID//{{{0}}}", registerType.GUID);
  33. ControlsCommands.Register(regKey);
  34. }
  35. private static void ArcGISCategoryUnregistration(Type registerType)
  36. {
  37. string regKey = string.Format("HKEY_CLASSES_ROOT//CLSID//{{{0}}}", registerType.GUID);
  38. ControlsCommands.Unregister(regKey);
  39. }
  40. private IHookHelper m_hookHelper;
  41. private INewCircleFeedback m_feedBack;
  42. private IPoint m_point;
  43. private Boolean m_isMouseDown;
  44. private IDisplayFeedback displayFeedback = null;
  45. public DrawCircleToolClass()
  46. {
  47. m_hookHelper = new HookHelperClass();
  48. }
  49. ~DrawCircleToolClass()
  50. {
  51. m_hookHelper = null;
  52. }
  53. public override void OnCreate(object hook)
  54. {
  55. m_hookHelper.Hook = hook;
  56. }
  57. public override bool Enabled
  58. {
  59. get
  60. {
  61. if (m_hookHelper.FocusMap == null) return false;
  62. return (m_hookHelper.FocusMap.LayerCount > 0);
  63. }
  64. }
  65. public override void OnMouseDown(int Button, int Shift, int X, int Y)
  66. {
  67. //Create a point in map coordinates
  68. IActiveView pActiveView = (IActiveView)m_hookHelper.FocusMap;
  69. m_point = pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y);
  70. displayFeedback = new NewCircleFeedbackClass();
  71. m_isMouseDown = true;
  72. }
  73. public override void OnMouseMove(int button, int shift, int x, int y)
  74. {
  75. if (!m_isMouseDown) return;
  76. IActiveView pActiveView = (IActiveView)m_hookHelper.FocusMap;
  77. if (m_feedBack == null)
  78. {
  79. m_feedBack = new NewCircleFeedbackClass();
  80. m_feedBack.Display = pActiveView.ScreenDisplay;
  81. m_feedBack.Start(m_point);
  82. }
  83. m_feedBack.MoveTo(pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y));
  84. }
  85. public override void OnMouseUp(int button, int shift, int x, int y)
  86. {
  87. if (!m_isMouseDown) return;
  88. IActiveView pActiveView = (IActiveView)m_hookHelper.FocusMap;
  89. ICircularArc pCircle;
  90. pCircle = m_feedBack.Stop();
  91. if (pCircle.Radius < 0.5)
  92. {
  93. m_feedBack = null;
  94. m_isMouseDown = false;
  95. }
  96. if (pCircle != null)
  97. {
  98. ISegmentCollection segCollection = new PolygonClass() as ISegmentCollection;
  99. object o = Type.Missing;
  100. segCollection.AddSegment(pCircle as ISegment, ref o, ref o);
  101. IPolygon polygon = segCollection as IPolygon;
  102. IRgbColor rgbColor = new RgbColorClass();
  103. rgbColor.Red = 255;
  104. IColor color = rgbColor;
  105. ISimpleFillSymbol simpleFillSymbol = new SimpleFillSymbolClass();
  106. simpleFillSymbol.Color = color;
  107. IElement element;
  108. IPolygonElement polygonElement = new PolygonElementClass();
  109. element = polygonElement as IElement;
  110. IFillShapeElement fillShapeElement = polygonElement as IFillShapeElement;
  111. fillShapeElement.Symbol = simpleFillSymbol;
  112. element.Geometry = polygon as IGeometry;
  113. IGraphicsContainer pGraphicContainer = pActiveView.GraphicsContainer;
  114. pGraphicContainer.AddElement(element, 0);
  115. pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
  116. }
  117. m_feedBack = null;
  118. m_isMouseDown = false;
  119. }
  120. }
  121. }

注意:要添加ArcEngine的相关程序集的引用,
如:ESRI.ArcGIS.ADF,ESRI.ArcGIS.Carti,ESRI.ArcGIS.Controls,ESRI.ArcGIS.Display,ESRI.ArcGIS.Geometry,ESRI.ArcGIS.SystemUI

10.在XAML中添加一个Button,并添加一个事件,DrawCircleTool_Click,在C#代码中添加该事件的代码如下:

  1. //绘制圆形
  2. private void DrawCircleTool_Click(object sender, RoutedEventArgs e)
  3. {
  4. ICommand DrawCircleTool = new DrawCircleToolClass();
  5. DrawCircleTool.OnCreate(mapControl.Object);
  6. mapControl.CurrentTool = (ITool)DrawCircleTool;
  7. }

11.最后执行程序,可以在加载地图文档,放大、缩小地图,也可以用自定义的画圆的工具在地图画圆。

使用XAML在WPF项目中承载ArcGIS Engine地图控件开发的更多相关文章

  1. 如何在WPF程序中使用ArcGIS Engine的控件

    原文 http://www.gisall.com/html/47/122747-4038.html WPF(Windows Presentation Foundation)是美国微软公司推出.NET ...

  2. WPF窗体中嵌入/使用WinForm类/控件(基于.NET Core)

    如题,WPF中嵌入WinForm的做法,网络上已经很多示例,都是基于.NET XXX版的. 今天King様在尝试WPF(基于.NET Core 3.1)中加入Windows.Forms.ColorDi ...

  3. ArcGIS Engine 笔记-控件类型

    控件 MapControl Map         地图控件 PageLayouControl      布局地图控件 TOCControl                目录控件 ToolbarCo ...

  4. 关于WPF中承载 ArcGIS控件。

    原文 http://www.cnblogs.com/zoe-j/archive/2011/05/18/2050208.html 之前就做过WPF的应用,之前承载的MapGIS的二次开发控件,今天写一下 ...

  5. WPF项目中解决ConfigurationManager不能用(转)

    https://blog.csdn.net/MOESECSDN/article/details/78107888 在WPF项目中遇到这样的问题,做一下笔记.希望对自己和读者都有帮助. 在aap.con ...

  6. Windows Presentation Foundation (WPF) 项目中不支持xxx的解决

    一般Windows Presentation Foundation (WPF) 项目中不支持xxx都是由于没引用相应的程序集导致,比如Windows Presentation Foundation ( ...

  7. WPF中不规则窗体与WebBrowser控件的兼容问题解决办法

    原文:WPF中不规则窗体与WebBrowser控件的兼容问题解决办法 引言 这几天受委托开发一个网络电视项目,要求初步先使用内嵌网页形式实现视频播放和选单,以后再考虑将网页中的所有功能整合进桌面程序. ...

  8. GMap.Net解决方案之在WinForm和WPF中使用GMap.Net地图插件的开发

    在做地理位置相关的开发时,总是面临高额地图引擎费用让大部分用户望而却步,加之地图数据又是天价,那么GMap.NET就是首选了,它本身就是开源免费,服务器可以在本地缓存,以后访问时就可以直接访问. 可以 ...

  9. WPF中不规则窗体与WindowsFormsHost控件的兼容问题完美解决方案

    首先先得瑟一下,有关WPF中不规则窗体与WindowsFormsHost控件不兼容的问题,网上给出的解决方案不能满足所有的情况,是有特定条件的,比如  WPF中不规则窗体与WebBrowser控件的兼 ...

随机推荐

  1. Populating Next Right Pointers in Each Node II 解答

    Question Follow up for problem "Populating Next Right Pointers in Each Node". What if the ...

  2. Java宝典(一)

    -switch语句能作用在byte上,能否作用在long上,能否作用在String上? -在switch(expr1)中,expr1只能是一个整数表达式或者枚举常量,整数表达式可以是int基本类型或I ...

  3. hdu 1159 Common Subsequence(LCS最长公共子序列)

    Common Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  4. pyqt 自定义例子学习

    # -*- coding: utf-8 -*- # python:2.x __author__ = 'Administrator' import sys from PyQt4.QtCore impor ...

  5. OS快速开发必备

    github:https://github.com/koknine (终于改成以前的了) 当前移动互联网行业太火爆,移动端的需求日益增长,很多开发人员每天都应对着各种需求,作为一名iOS开发人员,对于 ...

  6. (转)Apache+Tomcat集群配置

    本文Apache+Tomcat集群配置 基于最新的Apache和Tomcat,具体是2011年4月20日最新的Tomcat和Apache集群和负载均衡配置. 准备环境 Apache Apache是ht ...

  7. 01串(dp)

    01串 时间限制:1000 ms  |  内存限制:65535 KB 难度:2   描述 ACM的zyc在研究01串,他知道某一01串的长度,但他想知道不含有“11”子串的这种长度的01串共有多少个, ...

  8. TNS-00512: Address already in use-TNS-12542: TNS:address already in use

    监听启动或是停止时提示如下错误:TNS-12542: TNS:address already in use TNS-12560: TNS:protocol adapter error TNS-0051 ...

  9. HTTP协议之 简易浏览器(3)--转载

    简单的说,今天的全部工作就是 我的目的只有两个 1.加深对http协议的理解   2.深化对B/S结构的认识. 代码 1 /* 2 这个程序把主机地址写死了, 3 想更像的话,可以在加个输入.然后根据 ...

  10. Ext的labelWidth默认会给100

    Ext的textfield控件的labelWidth属性,如果没有设置这个属性,那么默认会给100,导致左侧有100px的留白