探索 Word 2007 开发(一):我的博客

探索 Word 2007 开发(一):我的博客

 

Written by Allen Lee

 

创建 Word 2007 插件项目

        这里,我将会使用Visual Studio 2008 Beta 2所带的VSTO(Visual Studio Tools for Office)来开发这个插件,此外,Office 2007也是必须的。

Figure 1

        如上图所示,你首先需要确保选择了 .NET Framework 3.5的项目,接着选择Visual C#\Office\2007\Word Add-in作为项目模板(当然,你也可以选择Visual Basic下面的那个),然后依次输入解决方案名字和项目名字,最后按下OK完成项目的创建。

Figure 2

        我们的项目包含了一个名为ThisAddIn.cs的代码文件,里面的ThisAddIn类就是我们的插件了。现在,我希望为Word 2007创建一个像Research那样的侧边栏,里面将包含与我的博客相关的信息:

Figure 3

 

创建"我的博客"侧边栏

        我不清楚以往怎样才能做到这样,但现在有了VSTO,你可以把以往所学的Windows Forms的技巧都用上,实际上,这样一个侧边栏就是一个用户控件(User Control)。现在,我们就来开发"我的博客"侧边栏。首先,在项目里添加一个名为MyBlogsUserControl的用户控件,接着在它上面拖放下列控件:

  • cbxBlogs:用于显示博客列表
  • btnViewBlog:在Internet Explorer中打开选定博客的主页
  • lbxRecentPosts:列出选定博客最近发布的帖子
  • btnViewPost:在Internet Explorer中打开选定帖子的网页
  • lbxDrafts:列出存在本地没有发布的帖子草稿
  • btnOpenDraft:在Word 2007中打开选定的帖子草稿

        MyBlogsUserControl在Visual Studio中的设计如下图所示:

Figure 4

        接下来就是把MyBlogsUserControl嵌到Word 2007里了,要做到这样,最简单的办法就是在插件启动的时候,以Custom Task Pane的方式加载控件。回到ThisAddIn.cs,我们可以看到,Visual Studio为我们准备好插件的Startup事件的Event Handler了:

 

        这样,我们只需要在方法里面插入下面的代码:

 

        作为应用程序级别(application-level)的扩展,Office 2007引入了Custom Task Pane这个概念,然而,直接通过Office PIA使用Custom Task Pane比较繁琐,于是,VSTO提供了一个简化方案,正如Code #02所示的那样。

增值服务区

        当然,别忘了引用VSTO的命名空间:

 

考验脑力区

  • using关键字共有多少种用法?它们分别是什么?

        现在来看看运行效果:

Figure 5

        到目前为止,"我的博客"侧边栏只是一个"空壳",接下来就是着手实现里面的逻辑了。

 

填充"我的博客"侧边栏

        假设"我的博客"侧边栏的相关文件安置在My Blogs文件夹里,该文件夹的结构如下图所示:

Figure 6

        虽然我们可以通过枚举My Blogs的子文件夹来填充cbxBlogs控件,然而我希望设计一个类来表示博客并且实现一定的数据绑定。回顾Figure 4,"我的博客"侧边栏应该具备如下特性:

  • 它会在启动时读取My Blogs文件夹里的相关信息,并且填充 cbxBlogs控件;
  • 当我们在博客列表中选择某个博客时,它会通过RSS获取该博客最近发布的帖子,并且填充lbxRecentPosts控件;
  • 当我们在博客列表中选择某个博客时,它会读取该博客帖子草稿文件夹里的数据,并且填充lbxDrafts控件;
  • 当我们在博客列表中选择某个博客时,按下View Blog按钮将会在Internet Explorer中打开该博客的主页;
  • 当我们在最近帖子列表中选择某个帖子时,按下View Post按钮将会在Internet Explorer中打开该帖子的网页;
  • 当我们在草稿列表中选择某个草稿时,按下Open Draft按钮将会在新的Word 2007中打开该草稿。

        明确这些需求后,我们就可以着手写代码了:

 

 

 

        对于Code #03,以下几点是需要说明的:

  • Post、Draft和Blog类都重写了ToString()方法,这是因为ComboBox和ListBox等控件会调用该方法并把返回的字符串用作条目的显示,重写该方法是为了让条目得到正确的显示。当然,如果你结合DataSource和DisplayMember来使用,也可以不重写ToString()方法。
  • Blog.GetRecentPosts()方法里使用Argotic Syndication Framework来进行RSS信息处理,所以你需要下载并安装它,然后在项目中引用相关的类库和Argotic.Core.Rss命名空间。
  • Blog.GetRecentPosts()方法里对RSS地址进行了假设,这个假设适用于博客园以及旗下其它网站,当然,你可以想出很多方法让它具备普遍适用性。
  • Blog.GetRecentPosts()方法里使用NetworkInterface. GetIsNetworkAvailable()方法判断当前网络是否连通,如果连通则获取数据,否则返回空数组。
  • Blog.GetDrafts()方法没有进行任何筛选,这里假设文件夹里面只包含.docx和/或.doc文件。由于这些文件将会用Word 2007打开,如果你可能往文件夹里放置Word 2007不能读取的文件,那么你最好为LINQ查询语句加入where来进行必要的过滤。
  • 在Blog.GetDrafts()方法里,我还假设My Blogs文件夹是放在"我的文档"里的,并且博客所在的文件夹名字和博客的名字一样,当然,这样我们就不能在博客的名字里面包含非法的路径字符了。

        我们可以让文件夹的名字和博客的名字相同,但却无法在这里包含博客的URL信息,而这又是很多操作的前提,于是我在My Blogs文件夹里放置一个Blogs.xml文件,里面包含了如下内容:

 

        有了这个文件,我们就可以顺利存取博客的URL信息了。另外,如果你希望让博客的名字不受路径的约束,即可以包含非法的路径字符,那么你可以为blog元素扩展一个directory属性用于存放路径,这样name属性就可以专门用于界面上的显示了。

增值服务区

        接下来就是把数据填充到"我的博客"侧边栏了,回到MyBlogsUserControl.cs,在构造函数里添加如下所示的代码:

 

        对于Code #04,以下几点是需要说明的:

  • 我们使用LINQ to XML获取Blogs.xml中博客的相关数据,并把这些数据绑定到博客列表上。
  • 我们获取blogs元素的defaultBlog属性的值,并用它来设置cbxBlogs.SelectedText属性,使得它所指定的默认博客成为当前所选定的博客。
  • 如果我们约定第一个blog元素就是默认博客,那么这里就不需要使用defaultBlog属性和设置SelectedText属性了,因为当我们把一个数据源绑定到DataSource属性时,它会在完成绑定后把第一个条目设为当前选定项,当然,此时会引发SelectedValueChanged(和其它相关的)事件。

        噢,别忘记cbxBlogs的SelectedValueChanged事件,下面是该事件的Event Handler:

 

        值得提醒的是,Blog.GetRecentPosts()方法所返回的数组的元素个数和对应博客的设置相关:

Figure 7

        现在来看看运行效果:

Figure 8

 

查看博客、最近帖子和存档草稿

        由于查看博客和查看最近帖子这两项操作都是"外包"给Internet Explorer的,我们可以简单地调用System.Diagnostics.Process.Start()方法,并传入选定对象的Url属性的值:

 

        对于存档草稿,我们可以使用Documents.Open()方法来打开,并传递选定存档草稿的Path属性的值:

 

        需要说明的是,对于Documents.Open()方法来说,除了第一个参数,其它参数都是可选的,但由于C#不支持这种可选参数,于是我们只好给它们传递Type.Missing。

 

        至此,"我的博客"侧边栏的开发要告一段落了,虽然我们还想让它变得更强大。作为一个Word 2007扩展插件,现在的"我的博客"侧边栏存在一个不可忽视的问题:它是随Word 2007启动而启动,而不是因用户的需要启动,并且一旦关闭就无法再次启动,除非重新打开Word 2007,这对于用户来说是无法接受的。下一回,我们将探讨扩展Word 2007的Ribbon,并尝试在它上面添加一个按钮来负责"我的博客"侧边栏的启动。

posted @ 2007-09-19 19:41 Allen Lee 阅读(3175) 评论(23)  编辑 收藏 所属分类: Office

  回复  引用  查看    
#1楼 2007-09-19 20:18 | Jeffers Yuan      
不错!
楼主居然把VSTO和LINQ弄得比较熟悉了,可喜可贺!
  回复  引用  查看    
#2楼 2007-09-19 21:13 | GOFI XIAO      
不错,学习了。
  回复  引用    
#3楼 2007-09-19 21:16 | yun [未注册用户]
这个blog看着真舒服
还是希望看到脱离Offcie开发Word的例子。否则因为Word.exe被当作外部线程调用,会出现很多潜在的问题。
  回复  引用  查看    
#5楼 [楼主]2007-09-19 21:43 | Allen Lee      
To Frank[CallFrank@gmail.com]:

一般而言,脱离 Office 的程序进行开发多见于服务器端应用,对于 Office 2007 来说,你可以考虑 OOXML(Office Open XML)。
  回复  引用    
#6楼 2007-09-20 02:50 | ganquan [未注册用户]
你好,请问博主对Office开发的加密和打包发行方面有什么经验吗?希望能看到这方面的文章。
  回复  引用  查看    
#7楼 2007-09-20 08:28 | aspnetx      
我们最近也有人在研究类似的东西,但平台是office2003
  回复  引用  查看    
#8楼 2007-09-20 08:41 | Robert Lee      
不错,有时间自己动手实践看看,学习中。
另,Allen兄也是团长的fans吗:D
  回复  引用  查看    
#9楼 2007-09-20 09:28 | 笑煞天      
不错,不错.
不知道Frank兄说的脱离Office开发Word是什么意思?
  回复  引用  查看    
#10楼 2007-09-20 09:31 | City22      
关于Word的blog,有很多问题想问博猪啊。

有关于MetaWeblog的资料以及如何在word下进行扩展

Word是用什么方法将doc文件转换为Html的?我以前用document.SaveAs来保存为HTML文件,然后再读这个文件用HtmlAgilityPack分析,但是效果很不理想。

想问问博猪,word下关于Blog这一套API可不可以介绍一下,以及如何扩展,比如发布blog,设置blog的分类和属性等。

还有关于Ribbon的,我只是看到了用Ribbon.xml来添加Tab、Button等,但怎么用代码获得Ribbon的对象?不管用什么方是,我怎么才能将自定义的一个button加入到系统默认的那个博客Tab中?

感谢博猪分享Word开发经验,期待下一片大作
  回复  引用  查看    
#11楼 [楼主]2007-09-20 12:20 | Allen Lee      
To ganquan:

我对 Office 的加密没有研究,至于部署,VSTO Orcas 支持 ClickOnce,你可以看看这篇文章:

VSTO: My Favorite Feature - ClickOnce Deployment(http://blogs.msdn.com/pstubbs/archive/2007/05/17/vsto-my-favorite-feature-clickonce-deployment.aspx

而本系列文章也会有一篇讲述使用 ClickOnce 部署这个插件的,如果你对此感兴趣,敬请留意本系列文章。

To City22:

1. 推荐你使用 XML-RPC.NET 进行 MetaWeblog 开发,你可以到 http://www.xml-rpc.net/ 下载这个类库。

2. 你可以结合 WordProcessingML 和 XSLT 来生成 HTML,这里给你推荐两篇文章:

Using WordProcessingML to Generate Clean HTML from Word(http://www.informit.com/articles/article.aspx?p=691502&seqNum=1

XHTML in Word 2007's blogging tool(http://blogs.msdn.com/brian_jones/archive/2006/05/22/602167.aspx

3. 关于 Ribbon 开发的细节,请留意本系列文章的下一回。

4. 对于 Word 2007 的博客功能的扩展,本系列文章(可能)会有一篇讲述这个内容。
  回复  引用  查看    
#12楼 [楼主]2007-09-20 12:21 | Allen Lee      
To Robert Lee:

团长确实挺有趣的 ^_^
  回复  引用  查看    
#13楼 2007-09-20 12:57 | Clark Zheng      
超棒,收藏了!
  回复  引用  查看    
#14楼 2007-09-20 17:30 | xiao_p      
...好久没有看到大大的新文章了
  回复  引用  查看    
#15楼 [楼主]2007-09-24 09:22 | Allen Lee      
To City22:

关于 Ribbon 开发的细节,请看《探索 Word 2007 开发(二):扩展 Ribbon》(http://www.cnblogs.com/allenlooplee/archive/2007/09/23/903520.html)。
  回复  引用  查看    
#16楼 2007-09-26 14:14 | 落叶舟      
感谢。
  回复  引用  查看    
#17楼 2007-09-27 19:52 | 韩现龙      
汗,我还在用Framework2.0,楼主都把Frame Work 3.5给研究成这样了...
以后我是不没法再混下去了?
  回复  引用  查看    
#18楼 2008-04-11 19:06 | 留恋星空      
mark
  回复  引用    
#19楼 2008-06-11 01:44 | bddlwzh [未注册用户]
一定要2007吗?在2003下能做这样的开发吗?
  回复  引用  查看    
#20楼 [楼主]2008-06-11 19:25 | Allen Lee      
@bddlwzh
Office 2003不支持Custom Task Pane,不过可以使用Actions Pane。
  回复  引用    
#21楼 2008-08-06 19:51 | ZHEFU [未注册用户]
博主您好:
拜读了您的这篇文章,深受启发。写的由浅入深、通俗易懂。
互联网上关于这方面的文章比较少,如此精妙的更是难得。

我参照您的自定义任务窗格也做了一个,它的功能是接受一个字符串,
返回一个标准代码文本。然后我新建了一个WORD文档,文档中有一个按钮,
我的问题是如何能在Word文档中访问到我任务窗格中自定义控件的事件?

谢谢
  回复  引用  查看    
#22楼 [楼主]2008-08-06 20:25 | Allen Lee      
@ZHEFU
如果你创建的是Word 2007 Add-in项目,那么你可以通过Globals.ThisAddIn.CustomTaskPanes访问到与当前插件相关的所有自定义任务窗格,找到你想要的自定义任务窗格,接着通过CustomTaskPane.Control可以访问到你添加这个自定义任务窗格关联的用户控件,然后通过这个用户控件对象实例访问你想要的事件。

另外,《探索 Word 2007 开发 II(一):引用 .NET Framework Class Library 在线文档》(http://www.cnblogs.com/allenlooplee/archive/2007/10/20/931494.html)里的Code 13给出了查找特定自定义任务窗格的示范代码,你可以在这个代码的基础上做一些修改。

Hope that helps.

标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2007-09-19 19:53 编辑过


相关链接: