使用XAML在WPF项目中承载ArcGIS Engine地图控件开发

简介: 原文 http://blog.csdn.net/flexmapserver/article/details/5868882 用Windows Form进行ArcGIS Engine二次开发时常见的形式,当然也可以用WPF来进行ArcEngine的二次开发。

原文 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代码看起来是这样:

[c-sharp] view plain copy print ?
  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;

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

[c-sharp] view plain copy print ?
  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事件中加载上述三个控件,如下:

       

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

 

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

        

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

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

          代码如下:

         

[c-sharp] view plain copy print ?
  1. public partial class App: Application  
  2. {  
  3.     public App ()  
  4.          {  
  5.          InitializeEngineLicense ();  
  6.     }  
  7.   
  8.     private void InitializeEngineLicense ()  
  9.     {  
  10.         AoInitialize aoi = new AoInitializeClass ();  
  11.   
  12.         esriLicenseProductCode productCode = esriLicenseProductCode.esriLicenseProductCodeEngine;  
  13.         if (aoi.IsProductCodeAvailable (productCode) == esriLicenseStatus.esriLicenseAvailable)  
  14.         {  
  15.             aoi.Initialize (productCode);  
  16.         }  
  17.     }  
  18. }  

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

           

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

           注意:要添加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#代码中添加该事件的代码如下:

           

[c-sharp] view plain copy print ?
  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.最后执行程序,可以在加载地图文档,放大、缩小地图,也可以用自定义的画圆的工具在地图画圆。

目录
相关文章
|
3月前
|
C# 开发者 Windows
WPF 应用程序开发:一分钟入门
本文介绍 Windows Presentation Foundation (WPF),这是一种用于构建高质量、可缩放的 Windows 桌面应用程序的框架,支持 XAML 语言,方便 UI 设计与逻辑分离。文章涵盖 WPF 基础概念、代码示例,并深入探讨常见问题及解决方案,包括数据绑定、控件样式与模板、布局管理等方面,帮助开发者高效掌握 WPF 开发技巧。
167 65
|
3月前
|
设计模式 前端开发 C#
WPF 项目中 MVVM模式 的简单例子说明
本文通过WPF项目中的加法操作示例,讲解了MVVM模式的结构和实现方法,包括数据模型、视图、视图模型的创建和数据绑定,以及命令的实现和事件通知机制。
|
4月前
|
容器 C# Docker
WPF与容器技术的碰撞:手把手教你Docker化WPF应用,实现跨环境一致性的开发与部署
【8月更文挑战第31天】容器技术简化了软件开发、测试和部署流程,尤其对Windows Presentation Foundation(WPF)应用程序而言,利用Docker能显著提升其可移植性和可维护性。本文通过具体示例代码,详细介绍了如何将WPF应用Docker化的过程,包括创建Dockerfile及构建和运行Docker镜像的步骤。借助容器技术,WPF应用能在任何支持Docker的环境下一致运行,极大地提升了开发效率和部署灵活性。
138 1
|
4月前
|
测试技术 C# 开发者
“代码守护者:详解WPF开发中的单元测试策略与实践——从选择测试框架到编写模拟对象,全方位保障你的应用程序质量”
【8月更文挑战第31天】单元测试是确保软件质量的关键实践,尤其在复杂的WPF应用中更为重要。通过为每个小模块编写独立测试用例,可以验证代码的功能正确性并在早期发现错误。本文将介绍如何在WPF项目中引入单元测试,并通过具体示例演示其实施过程。首先选择合适的测试框架如NUnit或xUnit.net,并利用Moq模拟框架隔离外部依赖。接着,通过一个简单的WPF应用程序示例,展示如何模拟`IUserRepository`接口并验证`MainViewModel`加载用户数据的正确性。这有助于确保代码质量和未来的重构与扩展。
99 0
|
4月前
|
持续交付 C# 敏捷开发
“敏捷之道:揭秘WPF项目中的快速迭代与持续交付——从需求管理到自动化测试,打造高效开发流程的全方位指南”
【8月更文挑战第31天】敏捷开发是一种注重快速迭代和持续交付的软件开发方法,通过短周期开发提高产品质量并快速响应变化。本文通过问题解答形式,探讨在Windows Presentation Foundation(WPF)项目中应用敏捷开发的最佳实践,涵盖需求管理、版本控制、自动化测试及持续集成等方面,并通过具体示例代码展示其实施过程,帮助团队提升代码质量和开发效率。
72 0
|
4月前
|
前端开发 C# 设计模式
“深度剖析WPF开发中的设计模式应用:以MVVM为核心,手把手教你重构代码结构,实现软件工程的最佳实践与高效协作”
【8月更文挑战第31天】设计模式是在软件工程中解决常见问题的成熟方案。在WPF开发中,合理应用如MVC、MVVM及工厂模式等能显著提升代码质量和可维护性。本文通过具体案例,详细解析了这些模式的实际应用,特别是MVVM模式如何通过分离UI逻辑与业务逻辑,实现视图与模型的松耦合,从而优化代码结构并提高开发效率。通过示例代码展示了从模型定义、视图模型管理到视图展示的全过程,帮助读者更好地理解并应用这些模式。
106 0
|
4月前
|
C# 开发者 Windows
勇敢迈出第一步:手把手教你如何在WPF开源项目中贡献你的第一行代码,从选择项目到提交PR的全过程解析与实战技巧分享
【8月更文挑战第31天】本文指导您如何在Windows Presentation Foundation(WPF)相关的开源项目中贡献代码。无论您是初学者还是有经验的开发者,参与这类项目都能加深对WPF框架的理解并拓展职业履历。文章推荐了一些适合入门的项目如MvvmLight和MahApps.Metro,并详细介绍了从选择项目、设置开发环境到提交代码的全过程。通过具体示例,如添加按钮点击事件处理程序,帮助您迈出第一步。此外,还强调了提交Pull Request时保持专业沟通的重要性。参与开源不仅能提升技能,还能促进社区交流。
47 0
|
4月前
|
区块链 C# 存储
链动未来:WPF与区块链的创新融合——从智能合约到去中心化应用,全方位解析开发安全可靠DApp的最佳路径
【8月更文挑战第31天】本文以问答形式详细介绍了区块链技术的特点及其在Windows Presentation Foundation(WPF)中的集成方法。通过示例代码展示了如何选择合适的区块链平台、创建智能合约,并在WPF应用中与其交互,实现安全可靠的消息存储和检索功能。希望这能为WPF开发者提供区块链技术应用的参考与灵感。
66 0
|
4月前
|
开发者 C# Windows
WPF与游戏开发:当桌面应用遇见游戏梦想——利用Windows Presentation Foundation打造属于你的2D游戏世界,从环境搭建到代码实践全面解析新兴开发路径
【8月更文挑战第31天】随着游戏开发技术的进步,WPF作为.NET Framework的一部分,凭借其图形渲染能力和灵活的UI设计,成为桌面游戏开发的新选择。本文通过技术综述和示例代码,介绍如何利用WPF进行游戏开发。首先确保安装最新版Visual Studio并创建WPF项目。接着,通过XAML设计游戏界面,并在C#中实现游戏逻辑,如玩家控制和障碍物碰撞检测。示例展示了创建基本2D游戏的过程,包括角色移动和碰撞处理。通过本文,WPF开发者可更好地理解并应用游戏开发技术,创造吸引人的桌面游戏。
199 0
|
4月前
|
开发者 C# 自然语言处理
WPF开发者必读:掌握多语言应用程序开发秘籍,带你玩转WPF国际化支持!
【8月更文挑战第31天】随着全球化的加速,开发多语言应用程序成为趋势。WPF作为一种强大的图形界面技术,提供了优秀的国际化支持,包括资源文件存储、本地化处理及用户界面元素本地化。本文将介绍WPF国际化的实现方法,通过示例代码展示如何创建和绑定资源文件,并设置应用程序语言环境,帮助开发者轻松实现多语言应用开发,满足不同地区用户的需求。
79 0