设为首页收藏本站Access中国

Office中国论坛/Access中国论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

返回列表 发新帖
楼主: faunus
打印 上一主题 下一主题

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

[复制链接]
21#
 楼主| 发表于 2014-3-22 16:26:35 | 只看该作者
  这个ribbon包含一个RibbonButton、一个RibbonSeparator、一个RibbonCheckBox和一个DialogBoxLauncher。按钮使用大显示样式,其OfficeImageId设置为StartAfterPrevious,显示如图40-13所示的钟表图像。(这些图像在设计期间不可见)。ribbon使用TabHome选项卡类型,其内容追加到Home选项卡上。
  ribbon有3个事件处理程序,每个处理程序都调用前面介绍的ThisAddIn中的一个实用方法:
  1. private void group1_DialogLauncherClick(object sender,
  2. RibbonControlEventArgs e)
  3. {
  4. // Show or hide task pane
  5. Globals.ThisAddIn.ToggleTaskPaneDisplay();
  6. }
  7. private void pauseCheckBox_Click(object sender, RibbonControlEventArgs e)
  8. {
  9. // Pause timer
  10. Globals.ThisAddIn.PauseOrResumeTimer(pauseCheckBox.Checked);
  11. }
  12. private void toggleDisplayButton_Click(object sender,
  13. RibbonControlEventArgs e)
  14. {
  15. // Show or hide task pane
  16. Globals.ThisAddIn.ToggleTaskPaneDisplay();
  17. }
复制代码
22#
 楼主| 发表于 2014-3-22 16:26:55 | 只看该作者
  ribbon还包含自己的实用方法SetPauseStatus(),如前所述,该方法由ThisAddIn中的代码调用,以选中复选框或取消复选框的选中。
  1. internal void SetPauseStatus(bool isPaused)
  2. {
  3. // Ensure checkbox is accurate
  4. pauseCheckBox.Checked = isPaused;
  5. }
复制代码
23#
 楼主| 发表于 2014-3-22 17:30:09 | 只看该作者
这个解决方案中的另一个组件是任务面板中使用的TimerDisplayPane用户控件,这个控件的布局如图
24#
 楼主| 发表于 2014-3-22 17:30:35 | 只看该作者
这个控件包含一个按钮、一个标签和一个列表框--这些都是很普通的显示控件,也可以用更漂亮的WPF控件替代它们。
该控件的代码保存了对文档计时器的一个本地引用,该引用在构造函数中设置:
  1. public partial class TimerDisplayPane : UserControl
  2. {
  3. private Dictionary < string, DocumentTimer > documentEditTimes;
  4. public TimerDisplayPane()
  5. {
  6. InitializeComponent();
  7. }
  8. public TimerDisplayPane(Dictionary < string, DocumentTimer >
  9. documentEditTimes) : this()
  10. {
  11. // Store reference to edit times
  12. this.documentEditTimes = documentEditTimes;
  13. }
复制代码




25#
 楼主| 发表于 2014-3-22 17:30:54 | 只看该作者
按钮事件处理程序调用RefreshDisplay()方法刷新计时器的显示:
  1. private void refreshButton_Click(object sender, EventArgs e)
  2. {
  3. RefreshDisplay();
  4. }
复制代码
26#
 楼主| 发表于 2014-3-22 17:31:13 | 只看该作者
RefreshDisplay()方法也从ThisAddIn中调用,如前所述。考虑到该方法的任务,这是一个相当复杂的方法,它还检查被监控文档的列表,与已加载文档的列表比较,并解决出现的问题。这段代码在VSTO应用程序中常常是必不可少的,因为COM Office对象模型的接口偶尔不能像期望的那样工作。这里的规则是防御式编码。
该方法首先清除timerList列表框中的当前计时器列表:
  1. internal void RefreshDisplay()
  2. {
  3. // Clear existing list
  4. this.timerList.Items.Clear();
复制代码
27#
 楼主| 发表于 2014-3-22 17:31:30 | 只看该作者
接着检查监控器。这个方法迭代Globals.ThisAddIn.Application.Documents集合中的每个文档,确定文档是被监控、未被监控、或被监控了但在上次刷新时改变了文件名。
要找出被监控的文档,只需比较当前的文档名和键的documentEditTimes集合中的文档名:
  1. // Ensure all docs are monitored
  2. foreach (Word.Document doc in Globals.ThisAddIn.Application.Documents)
  3. {
  4. bool isMonitored = false;
  5. bool requiresNameChange = false;
  6. DocumentTimer oldNameTimer = null;
  7. string oldName = null;
  8. foreach (string documentName in documentEditTimes.Keys)
  9. {
  10. if (doc.Name == documentName)
  11. {
  12. isMonitored = true;
  13. break;
  14. }
复制代码
28#
 楼主| 发表于 2014-3-22 17:31:50 | 只看该作者
如果文档名不匹配,就比较文档引用,以检测对文档名的修改,如下面的代码所示:
  1. else
  2. {
  3. if (documentEditTimes[documentName].Document == doc)
  4. {
  5. // Monitored, but name changed!
  6. oldName = documentName;
  7. oldNameTimer = documentEditTimes[documentName];
  8. isMonitored = true;
  9. requiresNameChange = true;
  10. break;
  11. }
  12. }
  13. }
复制代码
29#
 楼主| 发表于 2014-3-22 17:32:09 | 只看该作者
对于未监控的文档,需要创建一个新的监控器:
  1. // Add monitor if not monitored
  2. if (!isMonitored)
  3. {
  4. Globals.ThisAddIn.MonitorDocument(doc);
  5. }
  6. 名称改变的文档需要通过用于旧文档的监控器重新关联起来:
  7. // Rename if necessary
  8. if (requiresNameChange)
  9. {
  10. documentEditTimes.Remove(oldName);
  11. documentEditTimes.Add(doc.Name, oldNameTimer);
  12. }
  13. }
复制代码
30#
 楼主| 发表于 2014-3-22 17:32:29 | 只看该作者
调整了文档编辑计时器后,生成一个列表。代码还会检测引用的文档是否加载了,对于没有加载的文档,把IsActive属性设置为false,暂停该文档的计时器。这也是防御性编程方式:
  1. // Create new list
  2. foreach (string documentName in documentEditTimes.Keys)
  3. {
  4. // Check to see if doc is still loaded
  5. bool isLoaded = false;
  6. foreach (Word.Document doc in
  7. Globals.ThisAddIn.Application.Documents)
  8. {
  9. if (doc.Name == documentName)
  10. {
  11. isLoaded = true;
  12. break;
  13. }
  14. }
  15. if (!isLoaded)
  16. {
  17. documentEditTimes[documentName].IsActive = false;
  18. documentEditTimes[documentName].Document = null;
  19. }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-5-4 19:49 , Processed in 0.079446 second(s), 32 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

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