网上有很多关于在WPF中使用的Skyline提供的COM组件的教程,但大都雷同一律,其中很多的细节均为涉及,本文意在在其原基础上进行一些细节的补充。
工具:Visual Studio 2017
1. 在Visula Studio 中创建WPF工程
2. 分别添加对WindowsFormsIntegration,System.Windows.Forms,TerraExplorerX.dll(Skyline COM组件程序集) 程序集的引用。
3 实例代码:
MainWindow.xaml.cs
using System.Windows; using System.Windows.Forms.Integration; namespace SkylineDemo { /// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window { public SGWorld sGWorld = null; public MainWindow() { InitializeComponent(); //创建winform控件宿主对象 WindowsFormsHost te3DWindowHost = new WindowsFormsHost(); AxTerraExplorerX.AxTE3DWindow axTE3DWindow = new AxTerraExplorerX.AxTE3DWindow(); //将待寄宿的对象添加至宿主对象中 te3DWindowHost.Child = axTE3DWindow; //将该宿主对象添加至WPF控件中 DockPanelTE3DWindow.Children.Add(te3DWindowHost); WindowsFormsHost te3DInformatioinHost = new WindowsFormsHost(); AxTerraExplorerX.AxTEInformationWindow axTEInformationWindow = new AxTerraExplorerX.AxTEInformationWindow(); te3DInformatioinHost.Child = axTEInformationWindow; DockPanerTEInformation.Children.Add(te3DInformatioinHost); } /// <summary> /// 窗体初始化完毕后加载.fly文件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Window_Loaded(object sender, RoutedEventArgs e) { sGWorld = new SGWorld(); sGWorld.Project.Open(@"E:SkylineWebDemoDefault.fly"); } } }
MainWIndow.xaml
<Window x:Class="SkylineDemo.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:skyline="clr-namespace:AxTerraExplorerX;assembly=AxInterop.TerraExplorerX" xmlns:local="clr-namespace:SkylineDemo" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded"> <Grid > <Grid.ColumnDefinitions> <ColumnDefinition Width="*"></ColumnDefinition> <ColumnDefinition Width="4*"></ColumnDefinition> </Grid.ColumnDefinitions> <DockPanel Grid.Column="0" Background="Red" Name="DockPanerTEInformation" ></DockPanel> <DockPanel Grid.Column="1" Name="DockPanelTE3DWindow" Background="PowderBlue" ></DockPanel> <!-- 使用xaml方式 --> <!-- <DockPanel Grid.Column="0" x:Name="docProjectTree"> <WindowsFormsHost> <skyline:AxTEInformationWindow x:Name="projectTree"></skyline:AxTEInformationWindow> </WindowsFormsHost> </DockPanel> <DockPanel Grid.Column="1" x:Name="docSGWorld" Background="Orange"> <WindowsFormsHost> <skyline:AxTE3DWindow x:Name="sgWorld"></skyline:AxTE3DWindow> </WindowsFormsHost> </DockPanel> --> </Grid> </Window>
将上面的实例代码加入测试项目中后发现任然无法运行,原因是找不到TerraExplorerX 这个命名空间,经过查阅官方文档:
大意就是说:当一个com组件添加到.net(应该特质winform工程,wpf工具箱中无法直接使用com组件)工程后会自动创建interop dll。你可以在项目的obj目录中找到"Interop.TerraExplorerX.dll"。这个dll是com组件和.net组件的桥梁。
所以我们需要对wpf工程添加Interop.TerraExplorer.dll 的引用,如果没有可以新建WinForm工程,引入com后将生成的Interop.TerraExplorer.dll拷贝到wpf项目中,并添加引用,自此wpf项目已经可以编译,运行,自此我们已经顺利完成skyline com组件在wpf项目中的引入,如图:
PS:若wpf项目仍然无法正常运行,请做如下设置:
1. 将TerraExplorerX程序集嵌入互操作类型设置为False
2. 将解决方案平台架构设置为对应的架构,由于这个我使用的是TerraExplorerPro 6.6.1的版本,因此设置为x86架构,如果使用的是7.x的版本,那么对应配置为x64架构即可