设为首页收藏本站Access中国

Office中国论坛/Access中国论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

1234下一页
返回列表 发新帖
查看: 8186|回复: 33
打印 上一主题 下一主题

【示例】WORD下实现多窗口TASKPAN

[复制链接]
跳转到指定楼层
1#
发表于 2014-3-22 16:08:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  示例代码包含一个应用程序WordDocEditTimer,它维护着Word文档的一个编辑次数列表。本节将详细解释这个应用程序的代码,因为该应用程序演示了前面介绍的所有内容,还包含一些有益的提示。
  这个应用程序的一般操作是只要创建或加载了文档,就启动一个链接到文档名称上的计时器。如果关闭文档,该文档的计时器就暂停。如果打开了以前计时的文档,计时器就恢复。另外,如果使用Save As把文档保存为另一个文件名,计时器就更新为使用新文件名。
这个应用程序是一个Word应用程序级的插件,使用一个定制任务面板和一个ribbon菜单。
ribbon菜单包含一个按钮和一个复选框,按钮用于开关任务面板,复选框用于暂停当前活动的文档的计时器。包含这些控件的组添加到Home ribbon选项卡的最后。任务面板显示一组活动的计时器。

效果如下:



本帖子中包含更多资源

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

x
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享分享 分享淘帖 订阅订阅
推荐
 楼主| 发表于 2014-3-22 16:17:36 | 只看该作者
  因此,每个计时器都可以通过文档引用或文档名来定位。这是必要的,因为文档引用可以跟踪文档名的变化(这里没有可用于监控文档名变化的事件),文档名允许跟踪关闭、再次打开的文档。
  ThisAddIn类还维护一个CustomTaskPane对象列表(如前所述,Word中的每个窗口都需要一个CustomTaskPane对象):
  1. private List < Tools.CustomTaskPane > timerDisplayPanes;
复制代码
  插件启动时,ThisAddIn_Startup()方法执行了几个任务。首先它初始化两个集合:
  1. private void ThisAddIn_Startup(object sender, System.EventArgs e)
  2. {
  3. // Initialize timers and display panels
  4. documentEditTimes = new Dictionary < string, DocumentTimer > ();
  5. timerDisplayPanes = new
  6. List < Microsoft.Office.Tools.CustomTaskPane > ();
复制代码





回复 支持 1 反对 0

使用道具 举报

2#
 楼主| 发表于 2014-3-22 16:10:32 | 只看该作者
计时器通过DocumentTimer类来维护:
  1. public class DocumentTimer
  2. {
  3. public Word.Document Document { get; set; }
  4. public DateTime LastActive { get; set; }
  5. public bool IsActive { get; set; }
  6. public TimeSpan EditTime { get; set; }
  7. }
复制代码
  这段代码保存了对Microsoft.Office.Interop.Word. Document对象的一个引用、总编辑时间、计时器是否激活,以及它上一次激活的时间。ThisAddIn类维护这些对象的一个集合,这些对象与文档名关联起来:
  1. public partial class ThisAddIn
  2. {
  3. private Dictionary < string, DocumentTimer > documentEditTimes;
复制代码



4#
 楼主| 发表于 2014-3-22 16:18:03 | 只看该作者
  接着通过ApplicationEvents4_Event接口添加几个事件处理程序:
  1. // Add event handlers
  2. Word.ApplicationEvents4_Event eventInterface = this.Application;
  3. eventInterface.DocumentOpen += new Microsoft.Office.Interop.Word
  4. .ApplicationEvents4_DocumentOpenEventHandler(
  5. eventInterface_DocumentOpen);
  6. eventInterface.NewDocument += new Microsoft.Office.Interop.Word
  7. .ApplicationEvents4_NewDocumentEventHandler(
  8. eventInterface_NewDocument);
  9. eventInterface.DocumentBeforeClose += new Microsoft.Office.Interop.Word
  10. .ApplicationEvents4_DocumentBeforeCloseEventHandler(
  11. eventInterface_DocumentBeforeClose);
  12. eventInterface.WindowActivate += new Microsoft.Office.Interop.Word
  13. .ApplicationEvents4_WindowActivateEventHandler(
  14. eventInterface_WindowActivate);
复制代码



5#
 楼主| 发表于 2014-3-22 16:18:31 | 只看该作者
  这些事件处理程序用于监控文档的打开、创建和关闭,并确保ribbon上的Pause复选框保持最新状态。后一个功能是使用WindowsActivate事件跟踪窗口的激活状态来实现的。
  在这个事件处理程序中,最后一个任务是开始监控当前文档,把定制的任务面板添加到包含文档的窗口中:
  1. // Start monitoring active document
  2. MonitorDocument(this.Application.ActiveDocument);
  3. AddTaskPaneToWindow(this.Application.ActiveDocument.ActiveWindow);
  4. }
复制代码




6#
 楼主| 发表于 2014-3-22 16:19:16 | 只看该作者
  MonitorDocument()实用方法为文档添加一个计时器:
  1. internal void MonitorDocument(Word.Document Doc)
  2. {
  3. // Monitor doc
  4. documentEditTimes.Add(Doc.Name, new DocumentTimer
  5. {
  6. Document = Doc,
  7. EditTime = new TimeSpan(0),
  8. IsActive = true,
  9. LastActive = DateTime.Now
  10. });
  11. }
复制代码



7#
 楼主| 发表于 2014-3-22 16:19:56 | 只看该作者
  这个方法仅为文档创建了一个新的DocumentTimer对象。DocumentTimer引用文档,其编辑次数是0,且是在当前时间激活的。接着把这个计时器添加到documentEditTimes集合中,并关联到文档名中。
  AddTaskPaneToWindow()方法把定制任务面板添加到窗口中。这个方法首先检查已有的任务面板,确保窗口中还没有任务面板。Word中的另一个古怪的特性是如果在加载应用程序后,立即打开一个旧文档,默认的Document1文档就会消失,且不触发关闭事件。在访问包含任务面板的文档窗口时,这可能导致异常,所以该方法还检查表示是否出现该异常的ArgumentNullException:
  1. private void AddTaskPaneToWindow(Word.Window Wn)
  2. {
  3. // Check for task pane in window
  4. Tools.CustomTaskPane docPane = null;
  5. Tools.CustomTaskPane paneToRemove = null;
  6. foreach (Tools.CustomTaskPane pane in timerDisplayPanes)
  7. {
  8. try
  9. {
  10. if (pane.Window == Wn)
  11. {
  12. docPane = pane;
  13. break;
  14. }
  15. }
  16. catch (ArgumentNullException)
  17. {
  18. // pane.Window is null, so document1 has been unloaded.
  19. paneToRemove = pane;
  20. }
  21. }
复制代码




8#
 楼主| 发表于 2014-3-22 16:20:42 | 只看该作者
  如果抛出了一个异常,就从集合中删除错误的任务面板:
  1. // Remove pane if necessary
  2. timerDisplayPanes.Remove(paneToRemove);
复制代码

  如果窗口中没有任务面板,这个方法就添加一个:
  1. // Add task pane to doc
  2. if (docPane == null)
  3. {
  4. Tools.CustomTaskPane pane = this.CustomTaskPanes.Add(
  5. new TimerDisplayPane(documentEditTimes),
  6. "Document Edit Timer",
  7. Wn);
  8. timerDisplayPanes.Add(pane);
  9. pane.VisibleChanged +=
  10. new EventHandler(timerDisplayPane_VisibleChanged);
  11. }
  12. }
复制代码



9#
 楼主| 发表于 2014-3-22 16:21:16 | 只看该作者
  添加的任务面板是TimerDisplayPane类的一个实例。稍后介绍这个类。它添加时使用的名称是Document Edit Timer。另外,在调用CustomTaskPanes.Add()方法后,还为得到的CustomTaskPane的VisibleChanged事件添加了一个处理程序,这样在第一次显示任务面板时,可以刷新显示:
  1. private void timerDisplayPane_VisibleChanged(object sender, EventArgs e)
  2. {
  3. // Get task pane and toggle visibility
  4. Tools.CustomTaskPane taskPane = (Tools.CustomTaskPane)sender;
  5. if (taskPane.Visible)
  6. {
  7. TimerDisplayPane timerControl = (TimerDisplayPane)taskPane.Control;
  8. timerControl.RefreshDisplay();
  9. }
  10. }
复制代码



10#
 楼主| 发表于 2014-3-22 16:21:42 | 只看该作者
  TimerDisplayPane类有一个RefreshDisplay()方法,它在上面的代码中调用。这个方法刷新timerControl对象的显示。
  接着的代码确保监控所有的文档。首先创建新文档时,调用eventInterface_New- Document()事件处理程序,调用MonitorDocument()和前面介绍过的AddTaskPaneTo- Window()方法监控文档。
  1. private void eventInterface_NewDocument(Word.Document Doc)
  2. {
  3. // Monitor new doc
  4. MonitorDocument(Doc);
  5. AddTaskPaneToWindow(Doc.ActiveWindow);
复制代码




您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|站长邮箱|小黑屋|手机版|Office中国/Access中国 ( 粤ICP备10043721号-1 )  

GMT+8, 2024-4-27 00:39 , Processed in 0.154303 second(s), 35 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

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