自学内容网 自学内容网

【2025 ODA teigha系列开发教程一】实现WPF ViewDirectX DWG&DXF 模式图纸的预览查看,缩放

在这里插入图片描述

🎨 CAD图纸查看器

📖 项目介绍

嗨!欢迎来到CAD图纸查看器项目!这是一个基于WPF和Teigha SDK开发的专业CAD文件查看工具。无论你是工程师、设计师,还是其他需要查看CAD图纸的专业人士,这个工具都能帮你轻松处理DWG/DXF格式的工程图纸。

🎯 项目目标

  • 提供简单直观的CAD文件查看体验
  • 确保高性能的图纸渲染和操作响应
  • 支持业界标准的文件格式和操作方式

🛠️ 技术架构

核心技术

  • 界面框架:WPF (Windows Presentation Foundation)

    • 现代化的UI设计
    • 流畅的用户交互体验
  • 开发语言:C#

    • 强类型安全
    • 优秀的内存管理
  • CAD引擎:Teigha SDK (Open Design Alliance)

  • 渲染引擎:DirectX

    • 高性能图形渲染
    • 流畅的缩放和平移体验

✨ 功能特性

📂 文件操作

  • 文件打开

    • 支持.dwg格式(AutoCAD原生格式)
    • 支持.dxf格式(通用交换格式)
    • 智能错误提示和处理
  • 文件保存

    • 快速保存当前文件
    • 支持另存为不同版本
      • AutoCAD R24
      • AutoCAD R21
      • AutoCAD R18
      • AutoCAD R15
      • AutoCAD R14
      • AutoCAD R13
      • AutoCAD R12

🔍 视图控制

  • 智能缩放

    • 鼠标滚轮控制缩放
    • 以鼠标位置为中心点
    • 平滑的缩放效果
  • 视图导航

    • 直观的平移操作
    • 模型空间/图纸空间切换
    • 多视图支持

🎯 使用指南

快速开始

  1. 启动程序

    • 双击程序图标启动
    • 等待初始化完成
  2. 打开文件

    • 点击菜单中的"_Open"
    • 选择需要查看的CAD文件
    • 等待文件加载完成
  3. 查看操作

    • 使用鼠标滚轮进行缩放
    • 拖动视图进行平移
    • 使用菜单功能进行其他操作

🔧 开发者指南

环境配置

  1. 必需组件

    • Visual Studio 2019或更高版本
    • .NET Framework 4.7.2+
    • Teigha SDK(需要许可证,请联系我,我这有最新的许可证)
    • DirectX运行时
  2. 项目设置

    <!-- 项目引用配置 -->
    <Reference Include="Teigha.DatabaseServices">
    <Reference Include="Teigha.GraphicsSystem">
    <Reference Include="Teigha.Runtime">
    <Reference Include="Teigha.GraphicsInterface">
    <Reference Include="Teigha.Geometry">
    

📁 代码结构

```WpfViewDirectX/├── MainWindow.xaml.cs     # 主窗口逻辑实现│   ├── 文件操作相关方法│   ├── 视图控制相关方法│   └── 事件处理方法├── MainWindow.xaml        # 界面布局定义├── App.xaml              # 应用程序配置└── Properties/           # 项目属性配置


### 🔑 核心类说明

#### D3DImage.cs 显示控件
主窗口类,包含以下关键组件:
```csharp

using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media;
using Teigha.GraphicsSystem;
using Teigha.Runtime;

namespace WpfViewDirectX
{
    /// <summary>
    /// DirectX图像控件
    /// 负责处理DirectX渲染表面和WPF图像的交互
    /// </summary>
    public class WpfViewDirectXD3DImage : D3DImage
    {
        // 图形系统设备引用
        private Device m_gsDevice;
        
        // DirectX渲染表面的本机指针
        private IntPtr d3dSurfacePtr = IntPtr.Zero;
        
        // 用于VC10兼容性的反射方法
        private static System.Reflection.MethodInfo fSetBackBuffer = null;

        /// <summary>
        /// 构造函数
        /// </summary>
        public WpfViewDirectXD3DImage()
        {
        }

        /// <summary>
        /// 初始化DirectX图像
        /// </summary>
        /// <param name="device">图形系统设备</param>
        public void Initialize(Device device)
        {
            m_gsDevice = device;
        }

        /// <summary>
        /// 更新渲染表面
        /// 将DirectX渲染的内容更新到WPF图像
        /// </summary>
        public void UpdateSurface()
        {
            if (m_gsDevice == null)
                return;

            // 软件渲染模式下需要特殊处理
            if (IsSoftwareOnlyRenderMode() && !this.IsFrontBufferAvailable)
                return;

            UpdateBackBuffer();
        }

        /// <summary>
        /// 更新后台缓冲区
        /// </summary>
        void UpdateBackBuffer()
        {
            d3dSurfacePtr = GetD3DSurfaceFromDevice();
            SetD3DSurfacePtrToBackBuffer(d3dSurfacePtr);
        }

        /// <summary>
        /// 从设备获取DirectX渲染表面
        /// 在获取前需要更新设备,确保属性是最新的
        /// 获取新表面前需要释放旧表面
        /// </summary>
        private IntPtr GetD3DSurfaceFromDevice()
        {
            RXObject d3dSurfaceProp = null;
            using (Dictionary props = m_gsDevice.Properties)
            {
                if (props.Contains("D3DSurface"))
                    d3dSurfaceProp = props["D3DSurface"];
            }

            if (d3dSurfaceProp == null)
                return IntPtr.Zero;

            RxVariant v = new RxVariant(d3dSurfaceProp);
            return v.IntPtr;
        }

        /// <summary>
        /// 设置DirectX表面指针到后台缓冲区
        /// </summary>
        /// <param name="realSurfacePointer">DirectX表面指针</param>
        private void SetD3DSurfacePtrToBackBuffer(IntPtr realSurfacePointer)
        {
            if (realSurfacePointer == IntPtr.Zero)
                return;

            CallSetBackBufferWithLocks(realSurfacePointer);
            UpdateDirtyRect();
        }

        /// <summary>
        /// 使用锁定机制调用SetBackBuffer
        /// 确保线程安全的缓冲区更新
        /// </summary>
        /// <param name="surface">DirectX表面指针</param>
        private void CallSetBackBufferWithLocks(IntPtr surface)
        {
            // 通过反射获取SetBackBuffer方法
            if (fSetBackBuffer == null)
                fSetBackBuffer = typeof(WpfViewDirectXD3DImage).GetMethod("SetBackBuffer", 
                    new Type[] { typeof(D3DResourceType), typeof(IntPtr), typeof(bool) });

            this.Lock();

            // 调用SetBackBuffer方法设置后台缓冲区
            fSetBackBuffer.Invoke(this, new object[] {
                D3DResourceType.IDirect3DSurface9,
                surface,
                RenderOptions.ProcessRenderMode == System.Windows.Interop.RenderMode.SoftwareOnly
            });

            this.Unlock();
        }

        /// <summary>
        /// 更新脏矩形区域
        /// 标记需要重新渲染的区域
        /// </summary>
        private void UpdateDirtyRect()
        {
            Int32Rect updateRect = new Int32Rect();
            updateRect.X = updateRect.Y = 0;
            updateRect.Width = this.PixelWidth;
            updateRect.Height = this.PixelHeight;

            this.Lock();
            this.AddDirtyRect(updateRect);
            this.Unlock();
        }

        /// <summary>
        /// 清理后台缓冲区和渲染表面
        /// </summary>
        public void ClearBackBufferAndSurface()
        {
            CallSetBackBufferWithLocks(IntPtr.Zero);
            
            // 释放DirectX表面资源
            if (d3dSurfacePtr != IntPtr.Zero)
            {
                Marshal.Release(d3dSurfacePtr);
                d3dSurfacePtr = IntPtr.Zero;
            }
        }

        /// <summary>
        /// 释放资源
        /// 在控件销毁前调用,确保资源正确释放
        /// </summary>
        public void Deinitialize()
        {
            if (IsSoftwareOnlyRenderMode() && !this.IsFrontBufferAvailable)
                return;

            if (m_gsDevice == null)
                return;

            ClearBackBufferAndSurface();

            m_gsDevice.Dispose();
            m_gsDevice = null;
        }

        /// <summary>
        /// 检查是否为软件渲染模式
        /// </summary>
        /// <returns>是否为软件渲染模式</returns>
        private bool IsSoftwareOnlyRenderMode()
        {
            return RenderOptions.ProcessRenderMode == System.Windows.Interop.RenderMode.SoftwareOnly;
        }
    }
}

Control.xaml 显示控件

主窗口类,包含以下关键组件:

<UserControl x:Class="WpfViewDirectX.Control"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:WpfViewDirectX="clr-namespace:WpfViewDirectX"
  Height="Auto" Width="Auto" SizeChanged="UserControl_SizeChanged">
  <Grid Name="Grid">
        <Image x:Name ="drawImage"
         VerticalAlignment="Stretch"
         HorizontalAlignment="Stretch" Source="Images/oda_logo.png"/>
    </Grid>
</UserControl>

Control.xaml.cs

主窗口类,包含以下关键组件:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using Brushes = System.Windows.Media.Brushes;
using System.Windows;
using System.Windows.Interop;
using Size = System.Windows.Size;
using System.Windows.Media.Imaging;
using Teigha;
using Teigha.DatabaseServices;
using Teigha.GraphicsInterface;
using Teigha.GraphicsSystem;
using Teigha.Runtime;

namespace WpfViewDirectX
{
    /// <summary>
    /// CAD图纸渲染控件
    /// 负责处理图纸的显示和交互
    /// </summary>
    public partial class Control : UserControl
    {
        // 用于DirectX渲染的隐藏窗口,作为渲染表面
        Window HiddenWindowForRendering;
        
        // DirectX图像控件,用于显示渲染结果
        public WpfViewDirectXD3DImage d3dImage;
        
        // CAD数据库引用,存储图纸数据
        public Database database;
        
        // 视图设备,处理实际的渲染工作
        WpfViewDevice device;

        /// <summary>
        /// 构造函数
        /// 初始化控件和渲染相关组件
        /// </summary>
        public Control()
        {
            InitializeComponent();
            // 设置默认背景为ODA logo
            drawImage.Source = GetOdaLogo();
            // 初始化渲染设备
            device = new WpfViewDevice();
            d3dImage = new WpfViewDirectXD3DImage();
        }

        /// <summary>
        /// 初始化控件
        /// </summary>
        /// <param name="database">CAD数据库实例</param>
        public void Initialize(Database database)
        {
            this.database = database;
            // 初始化渲染设备
            device.Initialize(this);
            // 初始化DirectX图像
            d3dImage.Initialize(device.graphichsDevice);
            // 调整大小
            Resize();
            // 设置图像源
            drawImage.Source = d3dImage;
        }

        /// <summary>
        /// 获取或创建用于渲染的隐藏窗口的句柄
        /// </summary>
        /// <returns>窗口句柄源</returns>
        public HwndSource GetHwndSourceOfHiddenWindowForRendering()
        {
            if (HiddenWindowForRendering == null)
            {
                // 创建一个隐藏的窗口用于DirectX渲染
                HiddenWindowForRendering = new Window();
                HiddenWindowForRendering.Owner = Application.Current.MainWindow;
                HiddenWindowForRendering.Visibility = System.Windows.Visibility.Hidden;
                HiddenWindowForRendering.WindowStyle = System.Windows.WindowStyle.None;
                HiddenWindowForRendering.ShowInTaskbar = false;
                HiddenWindowForRendering.Background = Brushes.Transparent;
                HiddenWindowForRendering.AllowsTransparency = true;
                HiddenWindowForRendering.Show();
                HiddenWindowForRendering.Hide();
            }
            return HwndSource.FromVisual(HiddenWindowForRendering) as HwndSource;
        }

        /// <summary>
        /// 重新初始化控件
        /// 在打开新文件前调用,清理旧的资源
        /// </summary>
        public void Reinitialize()
        {
            // 清理渲染设备
            if (device != null)
            {
                device.Deinitialize();
                device = new WpfViewDevice();
            }

            // 清理DirectX图像
            if (d3dImage != null)
            {
                d3dImage.Deinitialize();
                d3dImage = new WpfViewDirectXD3DImage();
            }
        }

        /// <summary>
        /// 更新渲染内容
        /// </summary>
        public void Update()
        {
            device.graphichsDevice.Update();
        }

        /// <summary>
        /// 释放控件资源
        /// 在窗口关闭前调用,确保资源正确释放
        /// </summary>
        public void Deinitialize()
        {
            // 释放渲染设备资源
            if (device != null)
            {
                device.Deinitialize();
                device = null;
            }
            
            // 释放DirectX图像资源
            if (d3dImage != null)
            {
                d3dImage.Deinitialize();
                d3dImage = null;
            }
        }

        /// <summary>
        /// 调整控件大小
        /// 在窗口大小改变时更新渲染区域
        /// </summary>
        public void Resize()
        {
            if (device == null || d3dImage == null || device.graphichsDevice == null)
                return;

            // 清理缓冲区和渲染表面
            d3dImage.ClearBackBufferAndSurface();

            // 更新设备尺寸
            device.graphichsDevice.OnSize(GetControlSize());
            device.graphichsDevice.Update();

            // 更新渲染表面
            d3dImage.UpdateSurface();
        }

        /// <summary>
        /// 获取控件当前尺寸
        /// </summary>
        /// <returns>控件尺寸</returns>
        private System.Drawing.Size GetControlSize()
        {
            Size rect = RenderSize;
            System.Drawing.Size rectInt = new System.Drawing.Size((int)rect.Width, (int)rect.Height);
            return rectInt;
        }

        /// <summary>
        /// 获取ODA logo作为默认背景
        /// 在未加载图纸时显示
        /// </summary>
        /// <returns>logo图像源</returns>
        private static BitmapSource GetOdaLogo()
        {
            BitmapSource bitmapSource;
            try
            {
                // 加载ODA logo资源
                System.Drawing.Bitmap bitmap = WpfViewDirectX.Properties.Resources.oda_logo;

                // 转换为WPF可用的图像源
                bitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                    bitmap.GetHbitmap(),
                    IntPtr.Zero,
                    System.Windows.Int32Rect.Empty,
                    BitmapSizeOptions.FromWidthAndHeight(bitmap.Width, bitmap.Height));
            }
            catch (System.Exception ex)
            {
                // 如果加载失败,返回空
                bitmapSource = null;
            }

            return bitmapSource;
        }

        /// <summary>
        /// 控件大小改变事件处理
        /// </summary>
        private void UserControl_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            // 重新调整渲染区域大小
            Resize();
        }
    }
}


Device.cs类

using System;
using System.Windows;
using System.Windows.Interop;
using Teigha.DatabaseServices;
using Teigha.GraphicsInterface;
using Teigha.GraphicsSystem;
using Teigha.Runtime;

namespace WpfViewDirectX
{
    /// <summary>
    /// WPF视图设备类
    /// 负责管理CAD图形的渲染设备和布局
    /// </summary>
    public class WpfViewDevice
    {
        // 图形渲染设备,处理实际的绘图操作
        public Device graphichsDevice;
        
        // 布局辅助设备,处理模型空间和图纸空间的视图
        LayoutHelperDevice layoutHelperDevice;
        
        // 绘图控件引用
        Control drawControl;

        /// <summary>
        /// 构造函数
        /// </summary>
        public WpfViewDevice()
        {
        }

        /// <summary>
        /// 初始化视图设备
        /// </summary>
        /// <param name="drawControl">绘图控件实例</param>
        public void Initialize(Control drawControl)
        {
            this.drawControl = drawControl;

            try
            {
                // 加载预定义的渲染模块(可以是"WinDirectX"或"WinOpenGL")
                GsModule gsModule = (GsModule)SystemObjects.DynamicLinker.LoadModule("WinDirectX.txv", false, true);

                // 创建图形设备
                graphichsDevice = gsModule.CreateDevice();

                // 创建或获取隐藏窗口,用于OdGsDevice在窗口上渲染模型
                IntPtr renderWindow = drawControl.GetHwndSourceOfHiddenWindowForRendering().Handle;

                // 设置设备属性
                using (Dictionary props = graphichsDevice.Properties)
                {
                    // 设置窗口句柄(DirectX设备必需)
                    if (props.Contains("WindowHWND"))
                        props.AtPut("WindowHWND", new RxVariant(renderWindow));
                    
                    // 启用双缓冲
                    if (props.Contains("DoubleBufferEnabled"))
                        props.AtPut("DoubleBufferEnabled", new RxVariant(true));
                    
                    // 启用背面剔除
                    if (props.Contains("DiscardBackFaces"))
                        props.AtPut("DiscardBackFaces", new RxVariant(true));
                    
                    // 在渲染器端启用场景图
                    if (props.Contains("UseSceneGraph"))
                        props.AtPut("UseSceneGraph", new RxVariant(true));
                    
                    // 启用视觉样式
                    if (props.Contains("UseVisualStyles"))
                        props.AtPut("UseVisualStyles", new RxVariant(true));
                }

                // 设置图纸空间视口或平铺
                using (ContextForDbDatabase ctx = new ContextForDbDatabase(drawControl.database))
                {
                    // 启用图形系统模型
                    ctx.UseGsModel = true;
                    // 设置活动布局视图
                    layoutHelperDevice = LayoutHelperDevice.SetupActiveLayoutViews(graphichsDevice, ctx);
                }

                // 设置调色板(使用深色主题)
                layoutHelperDevice.SetLogicalPalette(Device.DarkPalette);

                // 执行初始大小调整
                drawControl.Resize();
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        /// <summary>
        /// 释放设备资源
        /// 确保按正确的顺序释放资源
        /// </summary>
        public void Deinitialize()
        {
            // 首先释放布局辅助设备
            if (layoutHelperDevice != null)
            {
                layoutHelperDevice.Dispose();
                layoutHelperDevice = null;
            }
            
            // 然后释放图形设备
            if (graphichsDevice != null)
            {
                graphichsDevice.Dispose();
                graphichsDevice = null;
            }
        }
    }
}

MainWindow.xaml主界面代码


<Window x:Class="WpfViewDirectX.MainWindow"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:WpfViewDirectX="clr-namespace:WpfViewDirectX"
  Title="MainWindow" Height="360" Width="564" MouseWheel="Window_MouseWheel">
  <Grid x:Name="mainGrid">
    <Grid.RowDefinitions>
      <RowDefinition Height="25" />
      <RowDefinition Height="100*" />
    </Grid.RowDefinitions>
    <Menu x:Name = "MainMenu" Grid.Row="0">
      <MenuItem Header="_File">
        <MenuItem Header="_Open"/>
        <MenuItem Header="_Save" IsEnabled="false" x:Name="MenuItemSave"/>
        <MenuItem Header="_SaveAs" IsEnabled="false" x:Name="MenuItemSaveAs"/>
        <MenuItem Header="_Exit"/>
      </MenuItem>
    </Menu>
    <WpfViewDirectX:Control
      x:Name="drawControl"
      Grid.Row="1"
      VerticalAlignment="Stretch"
      HorizontalAlignment="Stretch"
    />
  </Grid>
</Window>

MainWindow.xaml.cs后端代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using MenuItem = System.Windows.Controls.MenuItem;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Interop;
using System.Drawing;
using Teigha;
using Teigha.DatabaseServices;
using Teigha.GraphicsSystem;
using Teigha.Runtime;
using Teigha.GraphicsInterface;
using Teigha.Geometry;

namespace WpfViewDirectX
{
///
/// 主窗口类
/// 负责处理用户界面交互和CAD文件操作
///
public partial class MainWindow : Window
{
// Teigha服务实例,提供CAD核心功能
Teigha.Runtime.Services services;

    // CAD数据库,用于存储和管理图纸数据
    Database database = null;
    
    // 布局管理器,处理图纸布局
    LayoutManager lm;

    /// <summary>
    /// 构造函数
    /// 初始化窗口和CAD环境
    /// </summary>
    public MainWindow()
    {
        InitializeComponent();
        
        // 为所有菜单项添加点击事件处理
        foreach (MenuItem topLevelMenu in MainMenu.Items)
        {
            foreach (MenuItem itemMenu in topLevelMenu.Items)
            {
                itemMenu.Click += new RoutedEventHandler(MenuItem_Click);
            }
        }

        // 配置环境变量
        String strPath = Environment.GetEnvironmentVariable("PATH");
        String strPathModules = ""; // System.Environment.CurrentDirectory;
        Environment.SetEnvironmentVariable("PATH", strPathModules + ";" + strPath);

        // 初始化Teigha服务
        Teigha.Runtime.Services.odActivate(odActivate.UserInfo, odActivate.UserSignature);
        services = new Teigha.Runtime.Services();
    }

    /// <summary>
    /// 激活信息类
    /// 包含Teigha SDK的许可证信息
    /// </summary>
    internal class odActivate
    {
        // 用户信息(Base64编码)
        public const string UserInfo = "找我购买 微信:me1070202228";

        // 用户签名
        public const string UserSignature = "******找我购买 微信:me1070202228**************";
    }

    /// <summary>
    /// 窗口关闭时的清理工作
    /// </summary>
    protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
    {
        // 释放绘图控件资源
        drawControl.Deinitialize();

        // 释放数据库资源
        if (database != null)
            database.Dispose();

        // 释放Teigha服务
        services.Dispose();
    }

    /// <summary>
    /// 打开CAD文件
    /// </summary>
    /// <param name="sFilePath">文件路径</param>
    private void fileOpen(String sFilePath)
    {
        // 重新初始化绘图控件
        drawControl.Reinitialize();

        // 释放旧的数据库资源
        if (database != null)
            database.Dispose();

        // 清理布局管理器
        if (lm != null)
        {
            lm.LayoutSwitched -= new Teigha.DatabaseServices.LayoutEventHandler(reinitGraphDevice);
            HostApplicationServices.WorkingDatabase = null;
            lm = null;
        }

        bool bLoaded = true;
        database = new Database(false, false);

        try
        {
            // 根据文件扩展名选择打开方式
            String sExt = sFilePath.Substring(sFilePath.Length - 4);
            sExt = sExt.ToUpper();
            if (sExt.EndsWith(".DWG"))
            {
                // 打开DWG文件
                database.ReadDwgFile(sFilePath, FileOpenMode.OpenForReadAndAllShare, false, "");
            }
            else if (sExt.EndsWith(".DXF"))
            {
                // 打开DXF文件
                database.DxfIn(sFilePath, "");
            }
        }
        catch (System.Exception ex)
        {
            MessageBox.Show(ex.Message);
            bLoaded = false;
        }

        if (bLoaded)
        {
            // 更新窗口标题
            this.Title = String.Format("WpfViewDirectXApp - [{0}]", sFilePath);

            // 初始化绘图控件
            drawControl.Initialize(database);
        }
    }

    /// <summary>
    /// 重新初始化图形设备
    /// 在布局切换时调用
    /// </summary>
    private void reinitGraphDevice(object sender, Teigha.DatabaseServices.LayoutEventArgs e)
    {
        drawControl.Deinitialize();
        drawControl.Initialize(database);
    }

    /// <summary>
    /// 菜单项点击事件处理
    /// </summary>
    private void MenuItem_Click(object sender, RoutedEventArgs e)
    {
        MenuItem mItem = e.Source as MenuItem;
        if (mItem.IsEnabled)
        {
            String sHeader = mItem.Header as String;
            if ("_Open" == sHeader)
            {
                // 处理打开文件
                HandleOpenFile(mItem);
            }
            else if ("_Exit" == sHeader)
            {
                this.Close();
            }
            else if (database != null)
            {
                // 处理保存相关操作
                HandleSaveOperations(sHeader);
            }
        }
    }

    /// <summary>
    /// 处理文件打开操作
    /// </summary>
    private void HandleOpenFile(MenuItem mItem)
    {
        database = new Database(false, false);
        System.Windows.Forms.OpenFileDialog openFileDialog = new System.Windows.Forms.OpenFileDialog();
        openFileDialog.Filter = "dwg files|*.dwg|dxf files|*.dxf";
        openFileDialog.DefaultExt = "dwg";
        openFileDialog.RestoreDirectory = true;

        if (System.Windows.Forms.DialogResult.OK == openFileDialog.ShowDialog())
        {
            fileOpen(openFileDialog.FileName);
            MenuItem mPar = mItem.Parent as MenuItem;
            MenuItemSave.IsEnabled = true;
            MenuItemSaveAs.IsEnabled = true;
        }
    }

    /// <summary>
    /// 处理保存相关操作
    /// </summary>
    private void HandleSaveOperations(string sHeader)
    {
        if ("_Save" == sHeader)
        {
            // 直接保存
            if (database != null)
                database.Save();
        }
        else if ("_SaveAs" == sHeader)
        {
            // 另存为操作
            HandleSaveAs();
        }
    }

    public static ObjectId ActiveViewPortId(Database database)
    {
        if (database.TileMode)
        {
            return database.CurrentViewportTableRecordId;
        }
        else
        {

            using (BlockTableRecord paperBTR = (BlockTableRecord)database.CurrentSpaceId.GetObject(OpenMode.ForRead))
            {
                using (Layout layout = (Layout)paperBTR.LayoutId.GetObject(OpenMode.ForRead))
                {
                    return layout.CurrentViewportId;
                }
            }
        }
    }





    public void Dolly(View pView, int x, int y)
    {

        // helper function transforming parameters from screen to world coordinates

        Vector3d vector = new Vector3d(-x, -y, 0.0);

        vector = vector.TransformBy((pView.ScreenMatrix * pView.ProjectionMatrix).Inverse());

        pView.Dolly(vector);
    }



    //Zoom In / Zoom Out functionality

    private void Window_MouseWheel(object sender, MouseWheelEventArgs parameter)
    {
        try
        {

            System.Windows.Point pointToWindow = Mouse.GetPosition(parameter.MouseDevice.Captured);

            int delta = (parameter as MouseWheelEventArgs).Delta;

            using (Transaction tr = database.TransactionManager.StartTransaction())
            {
                using (DBObject pVpObj = ActiveViewPortId(database).GetObject(OpenMode.ForWrite))
                {
                    using (AbstractViewportData pAVD = new AbstractViewportData(pVpObj))
                    {
                        using (View pView = pAVD.GsView)
                        {

                            // camera position in world coordinates

                            Point3d positionCamera = pView.Position;

                            // TransformBy() returns a transformed copy

                            positionCamera = positionCamera.TransformBy(pView.WorldToDeviceMatrix);

                            double vx = pointToWindow.X - positionCamera.X;

                            double vy = pointToWindow.Y - positionCamera.Y;

                            Dolly(pView, (int)-vx, (int)-vy);

                            pView.Zoom(delta > 0 ? 1.0 / 0.9 : 0.9);

                            Dolly(pView, (int)vx, (int)vy);

                            pAVD.SetView(pView);

                        }
                    }
                }
                tr.Commit();
            }

            drawControl.Resize();
        }
        catch (System.Exception ex)
        {
            MessageBox.Show("Error on Zoom: " + ex.Message, "Error");
        }
    }
} // class MainWindow

} // namespace WpfViewDirectX


原文地址:https://blog.csdn.net/weixin_43118159/article/details/145266644

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!