明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 9625|回复: 10

[界面] 用WPF开发AUTOCAD.NET 程序的三种用法(学习笔记)

  [复制链接]
发表于 2010-12-28 22:05 | 显示全部楼层 |阅读模式
本帖最后由 qjchen 于 2011-12-20 13:02 编辑

用WPF开发AutoCAD.NET 程序的三种用法(学习笔记)
资料主要来源,自于Autodesk官方论坛中mikko的一个范例
学习者:qjchen

本贴是本人学习WPF的入门级笔记,各位其实打开该范例文件自然就懂了,高手们见笑了~

http://forums.autodesk.com/t5/NET/WPF-Controls-In-PaletteSet/m-p/2311530/highlight/true#M11201文中,mikko给出了一个非常有用的入门范例
http://forums.autodesk.com/autodesk/attachments/autodesk/152/11209/1/WPFacad.zip 。这个范例文件,非常好地给出了用VB.NET开发AUTOCAD WPF程序的三种方法
(1)采用PaletteSet面板工具内嵌wpf用户控件
(2)采用建立wpf控件转为wpf应用程序的方法
(3)利用.net语言直接生成wpf窗口
以下逐一进行学习讨论,并准备将其改造为c#代码方便后续的学习,并将期望将其拓展到SAP2000的开发中(经测试,SAP2000似乎还不支持WPF开发),毕竟这两种都是采用了类库开发模式,如何启动WPF窗口是一个值得学习的问题。
(1)采用PaletteSet面板工具内嵌wpf用户控件
说明:
对于这种wpf内嵌于ps面板中,Autocad官方有一个例子在此处
http://download.autodesk.com/media/adn/ACAD_Using_WPF_in_your_applications_02June2009.zip
压缩文件中的MyPaletteWebcast文件夹就是一个面板内嵌wpf窗口的例子
Kean也写过类似的例子
http://through-the-interface.typepad.com/through_the_interface/2009/08/hosting-wpf-content-inside-an-autocad-palette.html
还有一个例子是mjtd的翔麟曾经给过更加复杂的例子,用wpf Autocad查询一下google,你会发现第二个帖子就是了
http://bbs.mjtd.com/thread-80641-1-1.html
翔麟的.net CAD开发技术是很高的,特别是国内的Autocad和wpf的研究,现在能查到的网上资料,就大部分都是他的。
过程,首先,创建一个VB.NET的类库
接着,添加 acmgd.dll和acdbmgd.dll的引用,并在项目属性中,将这两个的复制本地设为false(C#则可以直接在解决方案资源管理器中修改)。
为了WPF的应用,添加另外几个.net的引用PresentationCore, PresentationFramework, System.Windows.Form, WindowsBase,  WindowsFormsIntegration
接下来,创建一个wpf控件,过程可以如下 在菜单-项目-添加用户控件 中找到wpf控件添加之,visual studio2008和2010的位置有一点点不同,并将这个用户控件重命名为 XamlCtrl.xaml
在这个用户控件的xaml中,贴入如下代码

  1. <UserControl x:Class="XamlCtrl"
  2.     xmlns="[url=http://schemas.microsoft.com/winfx/2006/xaml/presentation]http://schemas.microsoft.com/winfx/2006/xaml/presentation[/url]"
  3.     xmlns:x="[url=http://schemas.microsoft.com/winfx/2006/xaml]http://schemas.microsoft.com/winfx/2006/xaml[/url]" Width="300" Height="300">
  4.     <Grid>
  5.         <Grid.Background>
  6.             <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
  7.                 <GradientStop Color="#FF27323E" Offset="0"/>
  8.                 <GradientStop Color="#FFD8E8FA" Offset="1"/>
  9.             </LinearGradientBrush>
  10.         </Grid.Background>
  11.         <TextBlock Text="Just a few words to take up space." Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" />
  12.     </Grid>
  13. </UserControl>
复制代码


(可见此代码,可以直接用拖拉控件的方法得到,当然,加了一些线性渐变的颜色代码)
接下来,将默认生成的class1.vb中的代码,改为如下内容

  1. Imports Autodesk.AutoCAD.Runtime
  2. Imports System.Windows.Forms
  3. Imports System.Windows.Forms.Integration
  4. Public Class Class1
  5.     Public ps As Autodesk.AutoCAD.Windows.PaletteSet
  6.     Private eh As ElementHost
  7.     Private ctrlXaml As XamlCtrl
  8.     <CommandMethod("xamlPS")> Public Sub xamlPS()
  9.         If (ps = Nothing) Then
  10.             ps = New Autodesk.AutoCAD.Windows.PaletteSet("Pallet Set Example", New Guid("48CFD470-D15A-434b-BC94-6ADAF073025E"))
  11.             eh = New ElementHost()
  12.             eh.Dock = DockStyle.Fill
  13.             ps.Add("Pallet Set Example", eh)
  14.             ctrlXaml = New XamlCtrl()
  15.             ctrlXaml.InitializeComponent()
  16.             eh.Child = ctrlXaml
  17.         End If
  18.         ps.Visible = True
  19.     End Sub
  20. End Class


可见大部分内容还是可以接受的,就是ps这段有些复杂。不过基本也可懂,过程是创建一个面板,加入一个元素,并将XamlCtrl这个刚才创建的wpf用户自定义控件显示到此面板中。好了,可以进行一下测试。在项目属性的调试中,增加acad.exe的外部程序调试。我用2007和2011都可以调试通过。先按下F6,生成一下。
在visual studio中按F5,打开ACAD界面了,键入NETLOAD,找到你保存这个项目中的bin/debug目录,那个叫***.dll的文件就是了。加载之后,键入 xamlPS 这个我们定义的命令。看看,就是我们如下的界面了。



怎么样,挺高兴的吧。
接下来,你就可以添加各种你喜欢的元素了。
比如用windows expression studio 4.0直接创建各类漂亮的窗口了。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x

评分

参与人数 1威望 +1 明经币 +3 收起 理由
雪山飞狐_lzh + 1 + 3 精品文章

查看全部评分

 楼主| 发表于 2010-12-28 22:06 | 显示全部楼层
本帖最后由 qjchen 于 2010-12-28 22:09 编辑

(2)采用建立wpf控件转为wpf应用程序的方法
在上述已有内容的基础上,增加如下内容
创建一个wpf控件(因为无法直接添加wpf窗口,只能建立控件),过程可以如下:在菜单-项目-添加用户控件中找到wpf控件添加之,visual studio2008和2010的位置有一点点不一样,并将这个用户控件重命名为 frmXaml.xaml
在这个用户控件的xaml中,贴入如下代码


  1. <Window x:Name="frmXaml" xmlns="[url=http://schemas.microsoft.com/winfx/2006/xaml/presentation]http://schemas.microsoft.com/winfx/2006/xaml/presentation[/url]"
  2. xmlns:x="[url=http://schemas.microsoft.com/winfx/2006/xaml]http://schemas.microsoft.com/winfx/2006/xaml[/url]"
  3. x:Class="ToDazeReality.frmXaml"
  4. Title="Inherits Window" WindowStartupLocation="CenterScreen" WindowStyle="ThreeDBorderWindow" ResizeMode="CanResize"  Width="300" Height="400">
  5.     <Window.Background>
  6.         <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
  7.             <GradientStop Color="#FF27323E" Offset="0"/>
  8.             <GradientStop Color="#FFD8E8FA" Offset="1"/>
  9.         </LinearGradientBrush>
  10.     </Window.Background>
  11.     <Window.Resources>
  12.         <Style x:Key="ButtonBlue" BasedOn="{x:Null}" TargetType="{x:Type Button}">
  13.             <Setter Property="Template">
  14.                 <Setter.Value>
  15.                     <ControlTemplate TargetType="{x:Type Button}">
  16.                         <Grid>
  17.                             <Rectangle Stroke="#FF000000" RadiusX="9.5" RadiusY="9.5" x:Name="rectangle">
  18.                                 <Rectangle.Fill>
  19.                                     <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
  20.                                         <GradientStop Color="#FF091A2F" Offset="0"/>
  21.                                         <GradientStop Color="#FF5D8DC6" Offset="1"/>
  22.                                     </LinearGradientBrush>
  23.                                 </Rectangle.Fill>
  24.                             </Rectangle>
  25.                             <Rectangle Stroke="{x:Null}" RadiusX="9.5" RadiusY="9.5" Margin="2,1,2,0">
  26.                                 <Rectangle.Fill>
  27.                                     <LinearGradientBrush EndPoint="0.498,0.469" StartPoint="0.5,0">
  28.                                         <GradientStop Color="#59FFFFFF" Offset="0"/>
  29.                                         <GradientStop Color="#00FFFFFF" Offset="1"/>
  30.                                     </LinearGradientBrush>
  31.                                 </Rectangle.Fill>
  32.                             </Rectangle>
  33.                             <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" RecognizesAccessKey="True"/>
  34.                         </Grid>
  35.                         <ControlTemplate.Resources>
  36.                             <Storyboard x:Key="Storyboard1">
  37.                                 <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
  38.                                     <SplineColorKeyFrame KeyTime="00:00:00" Value="#FF5D8DC6"/>
  39.                                     <SplineColorKeyFrame KeyTime="00:00:00.1300000" Value="#FF5DC6A3"/>
  40.                                 </ColorAnimationUsingKeyFrames>
  41.                                 <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)">
  42.                                     <SplineColorKeyFrame KeyTime="00:00:00" Value="#FF091A2F"/>
  43.                                     <SplineColorKeyFrame KeyTime="00:00:00.1300000" Value="#FF0C4F39"/>
  44.                                 </ColorAnimationUsingKeyFrames>
  45.                             </Storyboard>
  46.                             <Storyboard x:Key="OutOfHere"/>
  47.                             <Storyboard x:Key="Storyboard2">
  48.                                 <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="rectangle">
  49.                                     <SplineColorKeyFrame KeyTime="00:00:00" Value="#FF5DC6A3"/>
  50.                                     <SplineColorKeyFrame KeyTime="00:00:00.2560000" Value="#FF5D8DC6"/>
  51.                                 </ColorAnimationUsingKeyFrames>
  52.                                 <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="rectangle">
  53.                                     <SplineColorKeyFrame KeyTime="00:00:00" Value="#FF0C4F39"/>
  54.                                     <SplineColorKeyFrame KeyTime="00:00:00.2560000" Value="#FF091A2F"/>
  55.                                 </ColorAnimationUsingKeyFrames>
  56.                             </Storyboard>
  57.                         </ControlTemplate.Resources>
  58.                         <ControlTemplate.Triggers>
  59.                             <Trigger Property="IsFocused" Value="True"/>
  60.                             <Trigger Property="IsDefaulted" Value="True"/>
  61.                             <Trigger Property="IsMouseOver" Value="True">
  62.                                 <Trigger.ExitActions>
  63.                                     <BeginStoryboard Storyboard="{StaticResource Storyboard2}" x:Name="OutOfHere_BeginStoryboard"/>
  64.                                 </Trigger.ExitActions>
  65.                                 <Trigger.EnterActions>
  66.                                     <BeginStoryboard Storyboard="{StaticResource Storyboard1}"/>
  67.                                 </Trigger.EnterActions>
  68.                             </Trigger>
  69.                             <Trigger Property="IsPressed" Value="True"/>
  70.                             <Trigger Property="IsEnabled" Value="False"/>
  71.                         </ControlTemplate.Triggers>
  72.                     </ControlTemplate>
  73.                 </Setter.Value>
  74.             </Setter>
  75.         </Style>
  76.     </Window.Resources>
  77.     <Grid>
  78.         <Button Style="{DynamicResource ButtonBlue}"  Name="btnClose" Width="50" Height="26" Foreground="White">Close</Button>
  79.     </Grid>
  80. </Window>
复制代码


(可以看出,这个代码其他地方也没有什么太特殊的,就是需要把user control的首尾改成Window而非原来的User control。同时,x:Class="ToDazeReality.frmXaml" 是一句很关键的话。)
接下来,修改原来的class1.vb,使内容有所增加如下


  1. Imports Autodesk.AutoCAD.Runtime
  2. Imports System.Windows.Forms
  3. Imports System.Windows.Forms.Integration
  4. Public Class Class1
  5.     Public ps As Autodesk.AutoCAD.Windows.PaletteSet
  6.     Private eh As ElementHost
  7.     Private ctrlXaml As XamlCtrl
  8.     <CommandMethod("xamlPS")> Public Sub xamlPS()
  9.         If (ps = Nothing) Then
  10.             ps = New Autodesk.AutoCAD.Windows.PaletteSet("Pallet Set Example", New Guid("48CFD470-D15A-434b-BC94-6ADAF073025E"))
  11.             eh = New ElementHost()
  12.             eh.Dock = DockStyle.Fill
  13.             ps.Add("Pallet Set Example", eh)
  14.             ctrlXaml = New XamlCtrl()
  15.             ctrlXaml.InitializeComponent()
  16.             eh.Child = ctrlXaml
  17.         End If
  18.         ps.Visible = True
  19.     End Sub
  20.     <CommandMethod("xamlForm")> Public Sub xamlForm()
  21.         Dim frmXaml As New ToDazeReality.frmXaml()
  22.         frmXaml.ShowDialog()
  23.         frmXaml = Nothing
  24.     End Sub
  25. End Class


好了,可以进行一下测试。在项目属性的调试中,增加acad.exe的外部程序调试。我用2007和2011都可以调试通过。先按下F6,生成一下。
在visual studio中按F5,打开ACAD界面了,键入NETLOAD,找到你保存这个项目中的bin/debug目录,那个叫***.dll的文件就是了。加载之后,键入 WPFfrm 这个我们定义的命令。看看,就是我们如下的界面了。


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x

评分

参与人数 1金钱 +20 收起 理由
wylong + 20

查看全部评分

 楼主| 发表于 2010-12-28 22:07 | 显示全部楼层
本帖最后由 qjchen 于 2010-12-28 22:13 编辑

(3)利用.net语言直接生成wpf窗口

这种方法我最早看到是在翔麟的这篇文章
http://bbs.mjtd.com/dispbbs.asp?boardid=33&Id=78758
里面采用c#直接建立wpf窗口,感觉这种方法挺好,甚至可以不用建立wpf控件了,但对使用者的要求要高些,使用者对wpf窗口界面的建立语句必须比较熟悉。
下面是一个建立过程
如上相同的步骤(刚才已做过的可以不用再做)
过程,首先,创建一个VB.NET的类库
接着,添加 acmgd.dll和acdbmgd.dll的引用,并在项目属性中,将这两个的复制本地设为false(C#则可以直接在解决方案资源管理器中修改)。
为了WPF的应用,添加另外几个.net的引用PresentationCore, PresentationFramework, System.Windows.Form, WindowsBase,  WindowsFormsIntegration
接下来,添加一个类文件(具体,在项目-添加类),这个类的名字比如叫做 frmWPF.vb
那么,修改其代码如下

  1. Imports System
  2. Imports System.Windows
  3. Imports System.Windows.Controls
  4. Namespace ToDazeReality
  5.     Public Class frmWPF
  6.         Inherits Window
  7.         Public Shared Sub Main()
  8.             Dim app As Application = New Application()
  9.             app.Run(New frmWPF())
  10.         End Sub
  11.         Private txtbox1 As TextBox
  12.         Public Sub New()
  13.             Title = "WPF acad sample"
  14.             Width = 400.0
  15.             Height = 80.0
  16.             Dim stack As StackPanel = New StackPanel()
  17.             Content = stack
  18.             Dim grid1 As Grid = New Grid()
  19.             grid1.Margin = New Thickness(3)
  20.             stack.Children.Add(grid1)
  21.             Dim rowdef As RowDefinition = New RowDefinition()
  22.             rowdef.Height = GridLength.Auto
  23.             grid1.RowDefinitions.Add(rowdef)
  24.             Dim lbl As Label = New Label()
  25.             lbl.Margin = New Thickness(5)
  26.             lbl.Content = "Enter something: "
  27.             lbl.VerticalContentAlignment = VerticalAlignment.Center
  28.             lbl.HorizontalAlignment = HorizontalAlignment.Left
  29.             lbl.Width = 150.0
  30.             grid1.Children.Add(lbl)
  31.             txtbox1 = New TextBox()
  32.             txtbox1.Margin = New Thickness(5)
  33.             txtbox1.Width = 150.0
  34.             txtbox1.VerticalContentAlignment = Windows.VerticalAlignment.Center
  35.             txtbox1.HorizontalAlignment = HorizontalAlignment.Center
  36.             txtbox1.Name = "TextBox1"
  37.             grid1.Children.Add(txtbox1)
  38.             Dim btn As Button = New Button()
  39.             btn.Margin = New Thickness(5)
  40.             btn.Content = "OK"
  41.             btn.HorizontalAlignment = HorizontalAlignment.Right
  42.             btn.Width = 75.0
  43.             btn.IsDefault = True
  44.             AddHandler btn.Click, New RoutedEventHandler(AddressOf OK_ButtonClick)
  45.             grid1.Children.Add(btn)
  46.         End Sub
  47.         Private Sub OK_ButtonClick(ByVal sender As Object, ByVal args As RoutedEventArgs)
  48.             MsgBox(txtbox1.Text)
  49.             Close()
  50.         End Sub
  51.     End Class
  52. End Namespace


可以看出,在这个vb代码中,直接用Inherits Window的方法,用VB建立了一个WPF窗口。
此时,修改class1.vb的内容如下

  1. Imports Autodesk.AutoCAD.Runtime
  2. Imports System.Windows.Forms
  3. Imports System.Windows.Forms.Integration
  4. Public Class Class1
  5.     Public ps As Autodesk.AutoCAD.Windows.PaletteSet
  6.     Private eh As ElementHost
  7.     Private ctrlXaml As XamlCtrl
  8.     <CommandMethod("xamlPS")> Public Sub xamlPS()
  9.         If (ps = Nothing) Then
  10.             ps = New Autodesk.AutoCAD.Windows.PaletteSet("Pallet Set Example", New Guid("48CFD470-D15A-434b-BC94-6ADAF073025E"))
  11.             eh = New ElementHost()
  12.             eh.Dock = DockStyle.Fill
  13.             ps.Add("Pallet Set Example", eh)
  14.             ctrlXaml = New XamlCtrl()
  15.             ctrlXaml.InitializeComponent()
  16.             eh.Child = ctrlXaml
  17.         End If
  18.         ps.Visible = True
  19.     End Sub
  20.     <CommandMethod("xamlForm")> Public Sub xamlForm()
  21.         Dim frmXaml As New ToDazeReality.frmXaml()
  22.         frmXaml.ShowDialog()
  23.         frmXaml = Nothing
  24.     End Sub
  25.     <CommandMethod("WPFfrm")> Public Shared Sub WPFfrm()
  26.         Dim wpffrm As New ToDazeReality.frmWPF
  27.         wpffrm.ShowDialog()
  28.         wpffrm = Nothing
  29.     End Sub
  30. End Class


好了,可以进行一下测试。在项目属性的调试中,增加acad.exe的外部程序调试。我用2007和2011都可以调试通过。先按下F6,生成一下。
在visual studio中按F5,打开ACAD界面了,键入NETLOAD,找到你保存这个项目中的bin/debug目录,那个叫***.dll的文件就是了。加载之后,键入 WPFfrm 这个我们定义的命令。看看,就是我们如下的界面了。


此贴仅为 学习mikko代码的学习记录过程,希望能对看本帖的您也有点用处~


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x

评分

参与人数 1金钱 +20 收起 理由
wylong + 20

查看全部评分

发表于 2010-12-29 10:59 | 显示全部楼层
楼主善于总结和分享精神值得大家学习,赞一个。
发表于 2010-12-29 12:30 | 显示全部楼层
谢谢分享...后续有时间也来看看...
发表于 2011-1-3 11:18 | 显示全部楼层
wpf有啥过人之处?用通常的编程方法可以实现相同的功能吗?
发表于 2011-6-30 17:31 | 显示全部楼层
本帖最后由 lxf0802 于 2011-6-30 17:32 编辑

    楼主的代码无法正常运行,直接在CAD里加载dll,出现以下错误
发表于 2011-6-30 21:15 | 显示全部楼层
看起来不错,不过exml是我永远的痛……
发表于 2013-5-28 00:55 | 显示全部楼层
WPF只能通过CAD的面板来显示吗?
发表于 2014-10-10 17:31 | 显示全部楼层
lxf0802 发表于 2011-6-30 17:31
楼主的代码无法正常运行,直接在CAD里加载dll,出现以下错误

你用的CAD07吧?
低版本CAD对WPF的兼容性实在是差,需CAD2010以上
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-4-26 00:27 , Processed in 0.302739 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表