惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
B
Blog RSS Feed
宝玉的分享
宝玉的分享
腾讯CDC
博客园_首页
T
Tailwind CSS Blog
月光博客
月光博客
博客园 - 司徒正美
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
M
MIT News - Artificial intelligence
A
About on SuperTechFans
云风的 BLOG
云风的 BLOG
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
有赞技术团队
有赞技术团队
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
大猫的无限游戏
大猫的无限游戏
MongoDB | Blog
MongoDB | Blog
博客园 - 聂微东
V
Visual Studio Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
SecWiki News
SecWiki News
美团技术团队
P
Privacy International News Feed
H
Help Net Security
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Microsoft Security Blog
Microsoft Security Blog
Know Your Adversary
Know Your Adversary
Y
Y Combinator Blog
D
DataBreaches.Net
Project Zero
Project Zero
T
The Blog of Author Tim Ferriss
Cyberwarzone
Cyberwarzone
C
Cybersecurity and Infrastructure Security Agency CISA
C
Cisco Blogs
S
Schneier on Security
G
GRAHAM CLULEY
博客园 - 三生石上(FineUI控件)
Cisco Talos Blog
Cisco Talos Blog
小众软件
小众软件
Forbes - Security
Forbes - Security
D
Docker
T
Tenable Blog
S
Secure Thoughts
雷峰网
雷峰网
S
Security @ Cisco Blogs
T
The Exploit Database - CXSecurity.com
The Cloudflare Blog
博客园 - 【当耐特】
Spread Privacy
Spread Privacy
阮一峰的网络日志
阮一峰的网络日志

博客园 - Jeffrey Sun

关于Duck Typing的性能分析 - Draft Composite Application Guidance (Prism) V4 Releases! 关于文件流Seek以及Read操作的一点不满 VS2010 "内存不足" 错误补丁 微软Visual Studio 2010 第三集:幸福要敏捷 详解.NET 4.0平行任务库中必须注意的三种关系 山雨欲来风满楼, 却待山花烂漫时 - 写在.NET 4.0和Visual Studio 2010发布前夜 - Jeffrey Sun [转载]微软4月13日发布Silverlight 4 团队基础生成自动化流程之最佳实践(VI) - 系统模块化条件编译 团队基础生成自动化流程之最佳实践(V) - 使用Desktop Build 团队基础生成自动化流程之最佳实践(IV) - 重写团队基础默认生成流程 谁是你的下一行CODE 团队基础生成自动化流程之最佳实践总论(III) – 重写生成号产生机制 团队基础生成自动化流程之最佳实践总论(I) – 自动化生成流程基础 团队基础生成自动化流程之最佳实践总论(II) – 程序集版本信息 Memory Reordering/Memory Model 及其对.NET的影响 从DWG到XAML (II) - DWFx格式解析及其和XPS的关系 从DWG到XAML (I) - 浅谈DWG历史,现状及方向 - Jeffrey Sun 当心Dictionary带来的一种隐式内存泄漏
从DWG到XAML (III) – .NET中的 XPS Packaging类库及一个DWFx Packaging类库的实现 (源码)
Jeffrey Sun · 2010-01-25 · via 博客园 - Jeffrey Sun

导读

DocumentViewer

      其实复杂的事情原本可以很简单. 你想要的那个轮子, 也许别人早就为你造好了. 在这里也是如此. 比如全部你想要的, 就是在你的系统前端可以直接查看DWG文件, 那么全部需要做的, 仅仅是简单的从DWG导出为DWFx文件, 然后使用WPF的DocumentViewer控件打开这个文件就可以了. 这个示例程序可以从这里获取.

XAML

  1.  <DocumentViewer Name="docViewer" />

Code-Behind : Load DWFx

  1.  XpsDocument xpsDocument = null;
  2.  
  3.  if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
  4. {
  5.      // If there's an existing document open, close it.
  6.      if (xpsDocument != null)
  7.          xpsDocument.Close();
  8.  
  9.      // Create an XpsDocument for the file specified by the user.
  10.      try
  11.     {
  12.          xpsDocument = new
  13.              XpsDocument(dlg.FileName, System.IO.FileAccess.Read);
  14.     }
  15.     catch (UnauthorizedAccessException)
  16.     {
  17.         System.Windows.MessageBox.Show(
  18.             String.Format("Unable to access {0}", dlg.FileName ) );
  19.         return;
  20.     }
  21.  
  22.     // For optimal performance the XPS document should be remain
  23.     // open while its FixedDocumentSequence is active in the
  24.     // DocumentViewer control.  When the XPS document is opened
  25.     // with the XpsDocument constructor ("new XpsDocument" above) a
  26.     // reference to it is automatically added to the PackageStore.
  27.     // The PackStore is a static application collection that contains
  28.     // a reference to each open package along the package's URI as
  29.     // a key.  Adding a reference of the XPS package to the
  30.     // PackageStore keeps the package open and avoids repeated opens
  31.     // and closes while the document content is being accessed by
  32.     // DocumentViewer control.  The XpsDocument.Dispose() method
  33.     // automatically removes the package from the PackageStore after
  34.     // the document is removed from the DocumentViewer control and
  35.     // is no longer in use.
  36.     docViewer.Document = xpsDocument.GetFixedDocumentSequence();

      DocumentViewer是WPF专为呈现XPS文件内容准备的控件. 它所呈现的内容叫做FixedDocument, 这完全符合XPS的标准. 我们的DWFx格式文件是与XPS兼容的, 所以也可以被DocumentViewer直接载入和显示.我们用DocumentViewer直接打开一个DWFx文件并仔细对比, 你会发现它所呈现出来的内容和在AutoCAD中精确地相同.

Captu3re      这一特点, 取决于DWG文件导出到DWFx文件的过程中所采取的处理方式. 在转化的过程中, 所有的图形地理信息, 包括直接描述和图块信息引用, 都被原地还原被进行相应的变换(比如旋转, 缩放), 然后将最终的图形信息全部写入到FixedPage文件中. 采取这样的行为, 保证了转换前后的呈现精确问题, 并且这种精确性的实现不依赖于转换后容器的特性.

      凡事有一利必有一弊. 这里面有个问题.  我们知道, 如果我们手里有图形的原信息, 有变换公式, 那么我们很容易就能得到变换后的图形. 反之, 如果我们有变换后的图形和变换公式, 虽然可能麻烦一些, 但是大多数情况下我们能得到图形的源信息. 但是, 如果我们有图形的源信息和变换后的图形, 那么在大多数情况下猜测变换公式是极其困难的; 如果我们仅有变换后的图形, 那么还愿图块的图形信息引用, 是根本不可能的. 现在我们得到的DWFx这个包, 就让我们处在了这个比较囧的处境中 - 我们有变换后的图形信息(都在FixedPage中), 除此之外, 关于图形的一切其他细节, 比如它是经过什么变换来的, 它和另外一个图块是不是同一类图形等这些信息, 什么都没有了.

好吧, 这实在是够麻烦的. 不过我们可以有一些折中的办法, 比如, 在设计时, 相同的图块, 我们给它定义一些自定义属性,来标记这些图块原本指代了同一类实体, 比如都指代了电脑. 我们有这些自定义属性就够了. 自定义的属性是可以被获得的, 这些属性都保存在DWFx包中的Object definition file文件中.

自定义属性才是这个系统能够自动化的关键!

      比如我们要建设一个网吧自动管理系统. 我们的DWG文件就是包括电脑摆放位置在内的网吧布局设计. 我们的期待能交互的实体是DWG文件中摆放的一台台电脑. 我们期待这个管理系统能自动读入DWG/DWFx文件来表示网吧电脑的陈列位置, 然后我能在这些电脑上点击选择操作, 比如杀毒, 比如下载设置文件等. 要达到这个目的, 我们依赖自定义属性就可以了. 我们可以要求设计厂商在DWG文件中对每一台电脑加上一个电脑编号. 到我们的系统中, 我们可以读出这个自定义属性, 从而实现自动化. DWG/DWFx文件标示了实体的位置, 自定义属性标示了实体的唯一标记并实现系统的互动.

      上一篇文章已经详细分析了DWFx包内各个文件的含义. 所以读取这些文件的内容是相对容易的. 不过看起来, 我们首先需要一个标尺类库, 来标示我们应该如何去读取,怎么读.

XPS Packaging类库

      .NET Framework在System.Windows.Xps.Packaging命名空间下, 提供了一系列的类型和方法来帮助我们显示和操作XPS文档. 虽然我们的DWFx文件格式上兼容XPS, 但是显然XPS Packaging这个类库是Generic的, 是为所有的XPS文件设计的, 所以不太可能使用这个类库来直接操作我们的DWFx文件内容(从上文的文件内部组织形式也能体现这种差异). 不过作为微软提供的类库, 它应该是我们想要实现的DWFx类库的最好的标杆.

      您可以从这个链接来查看和学习XPS Packaging类库: http://msdn.microsoft.com/en-us/library/system.windows.xps.packaging.aspx. 可以注意的几个类是XPSDocument, xxxSequenceReader/Writer, xxxDocumentReader/Writer, xxxPageReader/Writer. 聪明的你一定注意到了, 这几个类的名字几乎正好对应了上文分析的XPS文档的组织形式. 所以如果我们来写DWFx Packaging Library, 也要清楚的显示出DWFx文件内部的层次形式.

DWFx Packaging & Converting Library的实现

      废话不多说了, 点击这里下载笔者创建的一个DWFx Packaging & Converting 类库的实现. 这个类库一共包含了4个项目:

Captur23e JeffreySun.Dwfx : 基础项目, 包含了一些DWFx的基本信息, 以及错误处理等;

JeffreySun.Dwfx.Packing : Packaging类库, 实现读取DWFx文件包内容的功能;

JeffreySun.Dwfx.Converting : Converting类库, 将读取的DWFx文件包内容链接并转化为XAML + 自定义属性

JeffreySun.DWFX2XAMLConverter : 一个简单的示例程序.

      您一定要注意这段重要声明! 这一类库仅以学习目的发布, 你可以在你的项目中直接使用, 但是作者不保证该类库的完整性, 也不保证该类库中没有问题, 并且不提供任何技术支持. 作者强烈建议您在研究DWFx格式规范后实现自己的DWFx类库.

至少, 您得改一下类库的名字吧...不然老板会踢你的屁股的 :)