【2025 ODA teigha .NET系列开发教程 第二章】实现Winform和WPF ViewWinForms DWG&DXF 模式图纸的预览查看,缩放

📋 目录

  1. 项目概述
  2. 环境搭建
  3. 开发步骤

🎯 项目概述

这是一个基于Winform的CAD文件查看器,支持WPF,可以打开和查看DWG/DXF格式的CAD文件。对于新手开发者来说,这是一个很好的学习项目,可以了解:

  • WPF应用和Winform程序开发,
  • CAD文件处理
  • 图形渲染基础
  • Windows窗体应用

项目结构

📁 WpfViewWinForms

├── 📄 MainWindow.xaml.cs # 主窗口逻辑代码

├── 📄 MainWindow.xaml # 主窗口界面设计

├── 📄 DrawControl.cs # 绘图控件核心代码

├── 📄 DrawControl.resx # 绘图控件资源文件

└── 📄 DrawControl.Designer.cs # 设计器生成的代码

核心文件说明

  1. MainWindow.xaml

    • 这是应用程序的主界面
    • 包含菜单栏和绘图区域
    • 使用XAML语言描述界面布局
  2. MainWindow.xaml.cs

    • 主窗口的后台代码
    • 处理文件打开、保存等操作
    • 管理用户界面交互
  3. DrawControl.cs

    • CAD图纸显示的核心控件
    • 处理图形渲染
    • 管理视图操作

🛠️ 环境搭建

1. 基础环境准备

  1. 安装开发工具

  2. 下载Teigha SDK

2. 项目创建

  1. 创建新项目

    • 打开Visual Studio
    • 文件 -> 新建 -> 项目
    • 选择"WPF应用程序(.NET Framework)"
    • 项目名称:WpfViewWinForms
    • 框架:.NET Framework 4.7.2
  2. 添加引用

    • 在解决方案资源管理器中右键"引用"

    • 添加以下引用:

      ✓ Teigha.Common
      ✓ Teigha.Db
      ✓ Teigha.Ge
      ✓ System.Windows.Forms
      

📝 开发步骤

1. 设计主窗口界面

  1. 打开MainWindow.xaml
  2. 添加以下XAML代码
csharp 复制代码
<Window x:Class="WpfViewWinForms.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="360" Width="564">
    <Grid>
    <Menu Name = "MainMenu">
      <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>
    <WindowsFormsHost Height="258" HorizontalAlignment="Left" Margin="0,22,0,0" Name="winFormsHost" VerticalAlignment="Top" Width="542" />
  </Grid>
</Window>
csharp 复制代码
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 WpfViewWinForms
{

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        // Teigha服务实例
        Teigha.Runtime.Services tdSrv;
        // 数据库实例,用于存储和管理CAD图纸数据
        Database database = null;
        // 布局管理器
        LayoutManager lm;

        public MainWindow()
        {
            InitializeComponent();
            // 为所有菜单项添加点击事件处理
            foreach (MenuItem topLevelMenu in MainMenu.Items)
            {
                foreach (MenuItem itemMenu in topLevelMenu.Items)
                {
                    itemMenu.Click += new RoutedEventHandler(MenuItem_Click);
                }
            }

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

            // 激活Teigha服务
            Teigha.Runtime.Services.odActivate(odActivate.UserInfo, odActivate.UserSignature);
            tdSrv = new Teigha.Runtime.Services();

            // 创建并设置绘图控件
            DrawControl drawCtrl = new DrawControl();
            winFormsHost.Child = drawCtrl;
        }
        internal class odActivate
        {
            public const string UserInfo = "购买许可请联系微信 me1070202228";

            public const string UserSignature = "购买许可请联系微信 me1070202228";
        }
        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            ((DrawControl)winFormsHost.Child).Deinitialize();

            if (database != null)
                database.Dispose();

            tdSrv.Dispose();
        }

        /// <summary>
        /// 打开CAD文件的方法
        /// </summary>
        /// <param name="sFilePath">文件路径</param>
        private void fileOpen(String sFilePath)
        {
            // 如果已存在布局管理器,清理之前的设置
            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("WpfViewWinFormsApp - [{0}]", sFilePath);

                ((DrawControl)winFormsHost.Child).Reinitialize(database);
                /* userSt.LastOpenedFile = sFilePath;
                 UpdateMenuFile();
                 userSt.Save();
                 HostApplicationServices.WorkingDatabase = database;
                 lm = LayoutManager.Current;
                 lm.LayoutSwitched += new Teigha.DatabaseServices.LayoutEventHandler(reinitGraphDevice);
                 String str = HostApplicationServices.Current.FontMapFileName;

                 //menuStrip.
                 exportToolStripMenuItem.Enabled = true;
                 zoomToExtentsToolStripMenuItem.Enabled = true;
                 zoomWindowToolStripMenuItem.Enabled = true;
                 setAvtiveLayoutToolStripMenuItem.Enabled = true;
                 fileDependencyToolStripMenuItem.Enabled = true;
                 panel1.Enabled = true;
                 pageSetupToolStripMenuItem.Enabled = true;
                 printPreviewToolStripMenuItem.Enabled = true;
                 printToolStripMenuItem.Enabled = true;*/
            }
        }

        private void reinitGraphDevice(object sender, Teigha.DatabaseServices.LayoutEventArgs e)
        {
            //disableCommand();
            ((DrawControl)winFormsHost.Child).Reinitialize(database);
        }

        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)
                {
                    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;
                    }
                }//if ("_Open" == sHeader)
                if ("_Exit" == sHeader)
                {
                    this.Close();
                }
                if (database != null)
                {
                    if ("_Save" == sHeader)
                    {
                        if (database != null)
                            database.Save();
                    }
                    if ("_SaveAs" == sHeader)
                    {
                        System.Windows.Forms.SaveFileDialog saveAsFileDialog = new System.Windows.Forms.SaveFileDialog();
                        saveAsFileDialog.Filter = "dwg R24 file format(*.dwg)|*.dwg|dwg R24 file format(*.dwg)|*.dwg|dwg R21 file format(*.dwg)|*.dwg|dwg R18 file format(*.dwg)|*.dwg|dwg R15 file format(*.dwg)|*.dwg|dwg R14 file format(*.dwg)|*.dwg|dwg R13 file format(*.dwg)|*.dwg|dwg R12 file format(*.dwg)|*.dwg";
                        saveAsFileDialog.DefaultExt = "dwg";
                        saveAsFileDialog.RestoreDirectory = true;

                        if (System.Windows.Forms.DialogResult.OK == saveAsFileDialog.ShowDialog())
                        {
                            int version = saveAsFileDialog.FilterIndex % 7;
                            DwgVersion vers = DwgVersion.Current;
                            if (0 == version)
                                vers = DwgVersion.vAC12;
                            else
                            {
                                if (1 == version)
                                    vers = DwgVersion.vAC24;
                                else
                                {
                                    if (2 == version)
                                        vers = DwgVersion.vAC21;
                                    else
                                    {
                                        if (3 == version)
                                            vers = DwgVersion.vAC18;
                                        else
                                        {
                                            if (4 == version)
                                                vers = DwgVersion.vAC15;
                                            else if (5 == version)
                                                vers = DwgVersion.vAC14;
                                        }
                                    }
                                }
                            }//else if (0 == version)
                            if (Math.Truncate((double)saveAsFileDialog.FilterIndex / 7) == 0)
                                database.SaveAs(saveAsFileDialog.FileName, vers);
                            else
                                database.DxfOut(saveAsFileDialog.FileName, 16, vers);
                        }//if (System.Windows.Forms.DialogResult.OK == saveAsFileDialog.ShowDialog())
                    }//if ("_SaveAs" == sHeader)
                }//if (database != null)
            }//if (mItem.IsEnabled)
        }

        private void MenuItem_Click_1(object sender, RoutedEventArgs e)
        {

        }
    }

}

DrawControl.cs

csharp 复制代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Teigha;
using Teigha.DatabaseServices;
using Teigha.GraphicsInterface;
using Teigha.GraphicsSystem;
using Teigha.Runtime;

namespace WpfViewWinForms
{
  public partial class DrawControl : UserControl
  {
    // 用于绘图的Graphics对象
    Graphics graphics;
    // 布局辅助设备
    LayoutHelperDevice helperDevice;

    public DrawControl()
    {
      InitializeComponent();
    }

    /// <summary>
    /// 初始化绘图控件
    /// </summary>
    /// <param name="database">CAD数据库实例</param>
    public void Initialize(Database database)
    {
      try
      {
        graphics = Graphics.FromHwnd(this.Handle);
        // 加载预定义的渲染模块(可以是WinDirectX, WinGLES2或WinOpenGL)
        using (GsModule gsModule = (GsModule)SystemObjects.DynamicLinker.LoadModule("WinDirectX.txv", false, true))
        {
          // 创建图形设备
          using (Teigha.GraphicsSystem.Device graphichsDevice = gsModule.CreateDevice())
          {
            // 设置设备属性
            using (Dictionary props = graphichsDevice.Properties)
            {
              // 设置窗口句柄(DirectX设备需要)
              if (props.Contains("WindowHWND"))
                props.AtPut("WindowHWND", new RxVariant(this.Handle));
              // 设置DC句柄(位图设备需要)
              if (props.Contains("WindowHDC"))
                props.AtPut("WindowHDC", new RxVariant(graphics.GetHdc()));
              // 启用双缓冲
              if (props.Contains("DoubleBufferEnabled"))
                props.AtPut("DoubleBufferEnabled", new RxVariant(true));
              // 启用软件隐线消除
              if (props.Contains("EnableSoftwareHLR"))
                props.AtPut("EnableSoftwareHLR", new RxVariant(true));
              // 启用背面剔除
              if (props.Contains("DiscardBackFaces"))
                props.AtPut("DiscardBackFaces", new RxVariant(true));
            }

            // 设置数据库上下文
            ContextForDbDatabase ctx = new ContextForDbDatabase(database);
            ctx.UseGsModel = true;

            // 设置活动布局视图
            helperDevice = LayoutHelperDevice.SetupActiveLayoutViews(graphichsDevice, ctx);
          }
        }
        // 设置调色板
        helperDevice.SetLogicalPalette(Device.DarkPalette);
        // 设置输出范围
        Resize();
      }
      catch (System.Exception ex)
      {
        MessageBox.Show(ex.ToString());
      }
    }

    public void Reinitialize(Database database)
    {
      if (graphics != null)
        graphics.Dispose();
      if (helperDevice != null)
        helperDevice.Dispose();
      Initialize(database);
    }

    public void Deinitialize()
    {
      if (graphics != null)
        graphics.Dispose();
      if (helperDevice != null)
        helperDevice.Dispose();
    }

    public new void Resize()
    {
      if (helperDevice != null)
      {
        Rectangle r = this.Bounds;
        r.Offset(-this.Location.X, -this.Location.Y);
        // HDC assigned to the device corresponds to the whole client area of the panel
        helperDevice.OnSize(r);
        Invalidate();
      }
    }

    private void DrawControl_Paint(object sender, PaintEventArgs e)
    {
      if (helperDevice != null)
      {
        try
        {
          helperDevice.Update();
        }
        catch (System.Exception ex)
        {
          graphics.DrawString(ex.ToString(), new Font("Arial", 16), new SolidBrush(Color.Black), new PointF(150.0F, 150.0F));
        }
      }
    }
  }
}

DrawControl.Designer.cs代码

csharp 复制代码
namespace WpfViewWinForms
{
  partial class DrawControl
  {
    /// <summary> 
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary> 
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
      if (graphics != null)
        graphics.Dispose();
      if (helperDevice != null)
        helperDevice.Dispose();

      if (disposing && (components != null))
      {
        components.Dispose();
      }
      base.Dispose(disposing);
    }

    #region Component Designer generated code

    /// <summary> 
    /// Required method for Designer support - do not modify 
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
      this.SuspendLayout();
      // 
      // DrawControl
      // 
      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
      this.Name = "DrawControl";
      this.Paint += new System.Windows.Forms.PaintEventHandler(this.DrawControl_Paint);
      this.ResumeLayout(false);

    }

    #endregion
  }
}
相关推荐
csdn_aspnet36 分钟前
C# 给定欧氏平面中的一组线可以形成的三角形的数量
算法·平面·c#
Conmi·白小丑1 小时前
Conmi的正确答案——Rider中引入WebView2包(C#)
开发语言·c#
时光追逐者1 小时前
C#/.NET/.NET Core技术前沿周刊 | 第 22 期(2025年1.13-1.19)
开源·c#·.net·.netcore·微软技术
^@^lemon tea^@^2 小时前
WPF 引发类型为“System.Windows.Forms.AxHost+InvalidActiveXStateException”的异常 解决办法
windows·wpf·ocx控件开发错误
苏克贝塔2 小时前
WPF1-从最简单的xaml开始.md
wpf
踏上青云路2 小时前
WPF MVVM 模式如何监听IsVisibleChanged 事件
wpf
斯内科2 小时前
C#使用WMI获取控制面板中安装的所有程序列表
开发语言·c#·wmi
我曾经是个程序员2 小时前
C#操作Xml节点
xml·c#
Alasdair_lu4 小时前
WPF 字符串传值到后端
开发语言·wpf