平时做ArcEngine开发都是基于Winform. 自从装了VS2010之后,对WPF产生了非常浓厚的兴趣. 一直想结合WPF+ArcEngine做开发. 今天刚好在网上看到一点信息,尝试了一下,结果可行. 先将尝试过程公布一下:
1.使用WindowsFormsHost 控件.
WPF提供了承载(host) Windows form 控件的设置,允许开发在WPF应用中继续使用已存在的Windows Form 控件. 那么,实现这种可能的方法就是使用WindowsFormsHost 控件.WindowsFormsHost控件 允许在 WPF 页面上承载 Windows 窗体控件的元素.为单个window form控件提供了一个承载的容器,使得window form控件可以存在于WPF窗体或页面上.若要在 WPF 元素中承载 Windows 窗体控件,必须将 Windows 窗体控件分配给 Child 属性.有关WindowsFormsHost 控件的详细介绍,请参阅MSDN文档:
http://msdn.microsoft.com/zh-cn/library/system.windows.forms.integration.windowsformshost.aspx
2. 创建WPF应用程序
环境: VS2008 SP1+ArcEngine
创建一个WPF应用程序命名为WPFMapViewer,至于如何创建,这里就不多累赘了.
3.添加必要的引用
- ESRI.ArcGIS.AxControls—包含了 AxMapControl
- ESRI.ArcGIS.System—包含了 AoInitialiseClass类 (用于初始化 ArcGIS Engine 的许可)
- WindowsFormsIntegration—包含了WindowsFormsHost 控件
- System.Windows.Forms
- System.Drawing
4.将WindowsFormsHost 从工具箱中拖放到窗体上,并打开MapWindow.xaml,添加WindowsFormsHost 的命名空间
-
xmlns:i="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
-
5.为控件创建WindowsFormsHost . 由于一个WindowsFormsHost 只能承载一个window form的控件,因此我们需要为每一个我们用到的AE控件创建一个WindowsFormsHost .这里我们将会用到AxMapControl,AxToolbarControl,AxTOCControl.因此创建三个WindowsFormsHost 控件,分别命名为mapHost,toolbarHost,tocHost.
-
<i:WindowsFormsHost Height="32" Name="toolbarHost" VerticalAlignment="Top" />
<i:WindowsFormsHost HorizontalAlignment="Left" Margin="0,29,0,25" Name="tocHost" Width="166" />
<i:WindowsFormsHost Margin="167,29,0,25" Name="mapHost" /> -
6.经过以上的步骤后,完整的xaml应该是这样:
- < Window x:Class ="WPFMapViewer.MapWindow"
xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"
Title ="MapViewer Hosted in WPF" Height ="433.29" Width ="559.944" Loaded ="Window_Loaded" Background ="Beige"
MaxHeight ="600" MaxWidth ="840"
xmlns:i ="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration" >
< Grid >
< i:WindowsFormsHost Name ="mapHost" Margin ="174,30,0,22" />
< i:WindowsFormsHost Margin ="0,30,0,22" Name ="tocHost" HorizontalAlignment ="Left" Width ="173" />
< i:WindowsFormsHost Height ="30" Name ="toolbarHost" VerticalAlignment ="Top" />
< TextBlock Height ="23.75" VerticalAlignment ="Bottom" Name ="textBlock1" Margin ="0,0,7.056,0" > Ready </ TextBlock >
</ Grid >
</ Window >7.打开App.XAML.cs 文件,在里面添加AE的许可验证代码
public App ()
{
InitializeEngineLicense ();
}
private void InitializeEngineLicense ()
{
AoInitialize aoi = new AoInitializeClass ();
// more license choices could be included here
esriLicenseProductCode productCode = esriLicenseProductCode.esriLicenseProductCodeEngine;
if (aoi.IsProductCodeAvailable (productCode) == esriLicenseStatus.esriLicenseAvailable)
{
aoi.Initialize (productCode);
}
}8. 打开MapWindow.xaml.cs, 在这里编写本文的核心部分.
(1).引入命名空间
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Controls;(2).声明私有变量,包含三个控件:AxMapControl,AxToolbarControl,AxTOCControl
AxMapControl mapControl;
AxToolbarControl toolbarControl;
AxTOCControl tocControl;(3).创建一个用于初始化创建AE控件的函数,
/// <summary>
/// 创建Engine控件并将控件绑定到各自的 WindowsFormsHost 元素上
/// </summary>
void CreateEngineControls ()
{
// 设置 Engine 控件到每个host的Child属性上
mapControl = new AxMapControl ();
mapHost.Child = mapControl;
toolbarControl = new AxToolbarControl ();
toolbarHost.Child = toolbarControl;
tocControl = new AxTOCControl ();
tocHost.Child = tocControl;
}(4).此外,还需设置一些基本的属性,比如toolbarControl或tocControl必须和mapcontrol进行绑定;添加命令按钮到toolbarControl上;挂接mapControl相关事件等等
按 Ctrl+C 复制代码SetControlsProperty
Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->/// <summary>
/// 设置控件相关的属性
/// </summary>
private void SetControlsProperty ()
{
//设置控件之间的绑定关系
tocControl.SetBuddyControl (mapControl);
toolbarControl.SetBuddyControl (mapControl);
//添加命令按钮到toolbarControl
toolbarControl.AddItem ("esriControls.ControlsOpenDocCommand");
toolbarControl.AddItem ("esriControls.ControlsAddDataCommand");
toolbarControl.AddItem ("esriControls.ControlsSaveAsDocCommand");
toolbarControl.AddItem ("esriControls.ControlsMapNavigationToolbar");
toolbarControl.AddItem ("esriControls.ControlsMapIdentifyTool");
//设置空间属性
toolbarControl.BackColor =Color.FromArgb (255,245, 245, 220);
//挂接事件
mapControl.OnMouseMove +=new IMapControlEvents2_Ax_OnMouseMoveEventHandler(mapControl_OnMouseMove);
}按 Ctrl+C 复制代码(5).最后,当程序启动时,加载地图文档
void LoadMap()
{
string strMxd = @" e:\Untitled.mxd " ;
if (mapControl.CheckMxFile(strMxd))
mapControl.LoadMxFile(strMxd);
}(6).这样,整个过程就完成了. 完整的代码如下:
using System;
using System.Windows;
using System.Windows.Forms;
using System.Drawing;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Controls;
namespace WPFMapViewer
{
public partial class MapWindow: Window
{
AxMapControl mapControl;
AxToolbarControl toolbarControl;
AxTOCControl tocControl;
public MapWindow ()
{
InitializeComponent ();
CreateEngineControls ();
}
/// <summary>
/// 创建Engine控件并将控件绑定到各自的 WindowsFormsHost 元素上
/// </summary>
void CreateEngineControls ()
{
// 设置 Engine 控件到每个host的Child属性上
mapControl = new AxMapControl ();
mapHost.Child = mapControl;
toolbarControl = new AxToolbarControl ();
toolbarHost.Child = toolbarControl;
tocControl = new AxTOCControl ();
tocHost.Child = tocControl;
}
/// <summary>
/// 设置控件相关的属性
/// </summary>
private void SetControlsProperty ()
{
// 设置控件之间的绑定关系
tocControl.SetBuddyControl (mapControl);
toolbarControl.SetBuddyControl (mapControl);
// 添加命令按钮到toolbarControl
toolbarControl.AddItem ( " esriControls.ControlsOpenDocCommand " );
toolbarControl.AddItem ( " esriControls.ControlsAddDataCommand " );
toolbarControl.AddItem ( " esriControls.ControlsSaveAsDocCommand " );
toolbarControl.AddItem ( " esriControls.ControlsMapNavigationToolbar " );
toolbarControl.AddItem ( " esriControls.ControlsMapIdentifyTool " );
// 设置空间属性
toolbarControl.BackColor = Color.FromArgb ( 245 , 245 , 220 );
// 挂接事件
mapControl.OnMouseMove += new IMapControlEvents2_Ax_OnMouseMoveEventHandler(mapControl_OnMouseMove);
}
void LoadMap()
{
OpenFileDialog op = new OpenFileDialog();
op.Title = "打开地图文档";
op.Filter = "地图文档(*.mxd)|*.mxd";
op.ShowDialog();
string strMxd = op.FileName;
if (mapControl.CheckMxFile(strMxd))
mapControl.LoadMxFile(strMxd);
}
private void Window_Loaded ( object sender, RoutedEventArgs e)
{
SetControlsProperty();
// 加载地图
LoadMap();
}
private void mapControl_OnMouseMove ( object sender, IMapControlEvents2_OnMouseMoveEvent e)
{
textBlock1.Text = " X,Y Coordinates on Map: " + string .Format ( " {0}, {1} {2} " , e.mapX.ToString ( " #######.## " ), e.mapY.ToString ( " #######.## " ), mapControl.MapUnits.ToString ().Substring ( 4 ));
}
}
}