任务窗格 (task pane) 是 VSTO 提供的主要界面之一,运行时任务窗格的界面看起来如下。本文假设我们要实现一个方便自己进行拷贝和粘贴的多重剪贴板,实现将单元格中需要反复使用的文本加载到 ListBox,并且能够拷贝到选中的单元格中。
界面设计
任务窗格本质上是一个 User Control,在工程中新建一个 user control:
将 User Control 命名为 ClipBoardPro,设计界面如下:
在 ClipboardPro 类代码中,编写四个按钮单击事件的代码:
using Microsoft.Office.Interop.Excel;
using System;
using System.Windows.Forms;
using WinForm = System.Windows.Forms;
namespace VSTODemo
{
public partial class ClipBoardPro : UserControl
{
public ClipBoardPro()
{
InitializeComponent();
}
private void btnAdd_Click(object sender, EventArgs e)
{
string content = ThisAddIn.ExcelApp.ActiveCell.Value;
if (lstContent.FindStringExact(content) == WinForm.ListBox.NoMatches) {
lstContent.Items.Add(content);
}
}
private void btnCopy_Click(object sender, EventArgs e)
{
if (lstContent.SelectedIndex != -1) {
foreach(Range cell in ThisAddIn.ExcelApp.Selection) {
cell.Value = lstContent.Text;
}
}
}
private void btnClearAll_Click(object sender, EventArgs e) {
lstContent.Items.Clear();
}
private void btnClearCurrent_Click(object sender, EventArgs e) {
lstContent.Items.RemoveAt(lstContent.SelectedIndex);
}
}
}
加载任务窗格
为了实现任务窗格的复用,创建一个静态类:
namespace VSTODemo
{
public static class TaskPaneShared
{
public static Microsoft.Office.Tools.CustomTaskPane taskPane;
}
}
在 ThisAddIn 的 ThisAddIn_Startup 事件中加载:
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
ExcelApp = Globals.ThisAddIn.Application;
// 初始化TaskPane
ClipBoardPro clipboard = new ClipBoardPro();
TaskPaneShared.taskPane = Globals.ThisAddIn.CustomTaskPanes.Add(clipboard, "剪贴板");
TaskPaneShared.taskPane.DockPosition = MsoCTPDockPosition.msoCTPDockPositionRight;
TaskPaneShared.taskPane.DockPositionRestrict = MsoCTPDockPositionRestrict.msoCTPDockPositionRestrictNoChange;
TaskPaneShared.taskPane.Width = 500;
// VisibleChange Event
TaskPaneShared.taskPane.VisibleChanged += new System.EventHandler(taskpane_VisibleChanged);
}
默认情况下,Task Pane 位于界面的右侧停靠,允许通过 DockPosition
属性设置停靠在左右、上下或者浮动。DockPostionRestrict
属性设置是否允许用户改变停靠的位置。
显示和隐藏任务窗格
在 Ribbon1 中新建一个 checkbox,界面如下:
编写 cbShowTaskPanel_Click 事件:
private void cbShowTaskPanel_Click(object sender, RibbonControlEventArgs e)
{
TaskPaneShared.taskPane.Visible = cbShowTaskPanel.Checked;
}
因为用户也可以手工关闭任务窗格(其实是隐藏),为了保持界面同步,在 TaskPane 的 visibleChange 事件中编写如下代码: