網上有很多關於在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:\SkylineWebDemo\Default.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架構即可