接上文http://www.cnblogs.com/koffer/archive/
新建一个简单的例子
这篇文章是针对第一次接触VSTO的,因此,我将用一个简单的VSTO例子来给你建立一个基本的概念VSTO是什么。在安装了VSTO以后,你可以看到新的模版已经增加到你的.net中了,如下图。
根据你选择的语言,你既可以创建C# 工程,也可以创建VB.NET工程。首先,我们选择C#工程,选择Excel工作簿创建一个C#工程,编译用作Excel文档的Dll。
在创建了工程以后,点击运行或者Ctrl+F5来启动程序看看,并不像你熟悉的Windows窗体或者浏览器,它将打开一个Excel文档。因为我们还没有增加任何代码,所以只是打开一个空的文档,而且不做任何事情。如果你还没有保存它,你可以做任何你想做的事情。接下来,我们将修改这个文档,而且我们就可以在C#工程中使用了,现在请关闭这个文档,然后在调试状态下F5打开这个程序,Visual Studio.NET将会像上次一样打开一个Excel文档,这次,不要关闭这个文档,而是停止调试,Excel文档还是被关闭了。(Koffer注:我不知道作者想表达什么,莫非是如何关闭Excel?)
现在我们来为这个空的Excel文档增加一个按钮,到目前为止,这个过程很像在Windows窗体中增加一个按钮,因为你可能想到在Excel中增加一个按钮与在Windows窗体中一样的简单,但是非常不幸的告诉你VSTO并没有提供任何向导。代码本身与任何的C#工程一样,但是你必须手工的做所有的事情。我期待着下个版本能够提供这样一个向导。
执行UI
为了在Excel中增加一个按钮,你需要在工具栏上选择控件箱中的控件。(Koffer注:我第一次使用10分钟都没有找到这个工具箱在哪里,呵呵,所以我在这里多加了一张图片) 打开工具栏 .
正如你所看到的,你可以在Excel中增加各种控件,而且可以通过选择更多控件按钮,你可以从附加控件中选择你需要的控件。
现在,请像图中那样增加一个按钮,点击属性按钮,输入标题Click,把控件的ID命名为:btnClick,当作完这些以后,关闭控件工具箱,和属性窗口,同时保存文档。
这次,让我们去C#工程中看看有什么变化(Koffer注:其实什么变化都没有,两个东西不会同步,如果可以,就so nice 了),我们需要对刚才在文档中添加的按钮增加事件处理。你可能已经知道了,我们需要使用FindControl 方法来找到Excel文档中的按钮btnClick,代码如下:
/// 在当前工作簿中查找具有指定名称的控件。
/// </summary>
/// <param name='name'>要查找的控件的名称。</param>
/// <returns>
/// 返回指定的控件,如果未找到该控件则返回空。
/// </returns>
object FindControl(string name )
{
return FindControl(name, (Excel.Worksheet) ThisWorkbook.ActiveSheet);
}
/// <summary>
/// 返回指定工作簿中具有指定名称的控件。
/// </summary>
/// <param name='name'>要查找的控件的名称。</param>
/// <param name='sheet'>包含该控件的工作簿对象。</param>
/// <returns>
/// 返回指定的控件,如果未找到该控件则返回空。
/// </returns>
object FindControl(string name, Excel.Worksheet sheet )
{
Excel.OLEObject theObject;
try
{
theObject = (Excel.OLEObject) sheet.OLEObjects(name);
return theObject.Object;
}
catch
{
// 如果未找到该控件,则返回空。
}
return null;
}
这些框架代码都是.net自动生成的,有两个重载的FindControl 方法,两个参数的方法接受控件的ID和控件所在Sheet,另外一个方法只有一个参数,把当前的活动Sheet作为参数传递近来调用第一个FindControl 方法.FindControl 方法调用表单(sheet)的OLE对象,并返回OLE对象。只有FindControl 方法返回的OLE对象与MSForm中的控件相关,例如,Command Button 对应CommandButton,Text控件对应TextBox。而且你在代码中还可以看到,如果FindControl方法找不到任何控件,将会返回null值,所以需要一直检测FindControl 方法的返回值。如下:
MSForms.CommandButton btnClick = (MSForms.CommandButton) FindControl("btnClick");
然后,你可以如下增加事件处理函数,增加这个事件就像在Windows窗体中一样,只不过没有向导。
btnClick.Click += new Microsoft.Vbe.Interop.Forms.CommandButtonEvents_ClickEventHandler(btnClick_Click);
使用Visual Studio .NET的智能感知,你不需要输入这么长的代码,而是简单的使用<tab>键就可以自动帮你增加这行代码。(Koffer注:发现作者的基本功很好,而且文笔也很不错!)现在,当按钮被点击的时候,我们让他设置文档中的Text。在作这个之前,然我们先了解一下Excel的结构:Excel可以被分成4个对象,应用程序、工作表、活动表、区域或者单元格。应用程序对象代表Excel应用程序本身,工作表代表用户工作的地方。活动表带表文档中的一页,而区域代表页中的几个或者一个单元格。因为这样的结构,每个元素都提供了自己的属性和事件。
如上图,区域代表页中的几个或者一个单元格。因为区域被称为Excel的一个工作单元,为了输出字符串A1,我们必须为A1找到单元格,根据单元格的名称非常容易找到这个单元格。如下代码:把单元格的名称作为参数传入,就可以返回相应的区域。
{
Excel.Worksheet sheet = (Excel.Worksheet) ThisApplication.Sheets.get_Item(1);
Excel.Range rng = sheet.get_Range ( "A1", "A1" );
rng.Value2 = "Hello, Excel";
MessageBox.Show("Yes,you are ok!"); // Add by Koffer 用意何在?
}
当我写这个例子的时候,我就想设置这个Text的属性的名称应该就像Text这个名称一样,但是,我发现它却是Value2(Text属性是一个只读的属性),我想这将在下一个版本中更新。
为了测试如上的代码,运行程序,我们就可以在A1单元格中看到"Hello, Excel"的字样!
待续......