平时做ArcEngine开发都是基于Winform. 自从装了VS2008之后,对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应该是这样:
MapWindow.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的许可验证代码
App
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控件的函数,
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;
}
(4).此外,还需设置一些基本的属性,比如toolbarControl或tocControl必须和mapcontrol进行绑定;添加命令按钮到toolbarControl上;挂接mapControl相关事件等等
SetControlsProperty
///
<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);
}
(5).最后,当程序启动时,加载地图文档
void
LoadMap()
{
string
strMxd
=
@"
e:\Untitled.mxd
"
;
if
(mapControl.CheckMxFile(strMxd))
mapControl.LoadMxFile(strMxd);
}
(6).这样,整个过程就完成了. 完整的代码如下:
MapWindow
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()
{
string
strMxd
=
@"
e:\Untitled.mxd
"
;
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
));
}
}
}
9. 调试,按F5.效果图如下:
10.总结
通过本试验可以得到一个启发:借助WindowsFormsHost,我们也能像WinForm一样开发我们的AE程序,同时,我们也注意到,在WPF中使用AE开发和在WinForm上没有很大的区别, 可以像在Winform下开发一样灵活.这里只是抛砖引玉, 有兴趣的可以更深入地开发一些复杂的AE功能,比方说自定义命令按钮并与地图交互等.
11. 实例下载
/Files/JinDin/WPFMapViewer.rar