VSTO学习(六)——创建Outlook解决方案
本专题概要
- 引言
- Outlook对象模型
- 自定义Outlook窗体
- 小结
一、引言
在上一个专题中,为大家简单介绍了下如何创建Word解决方案的,所以本专题中将为大家介绍下Outlook相关的内容。我们从Visual Studio 2010 中Office节点下的模板中我们可以看到,Outlook只有外接程序的模板,并没有提供像Word或Excel这样的文档级的模板,所以VSTO没有为Outlook解决方案创建宿主项和宿主控件(Excel和Word中VSTO都为他们提供了宿主项和宿主控件,因为这些控件是文档级别的。对于宿主控件和宿主项的具体内容可以参考本系列的专题一)。为了能够更好地创建Outlook的解决方案,下面就具体介绍下Outlook对象模型。
二、Outlook对象模型
2.1 Application 对象
Application对象代表着Outlook应用程序,并且也是Outlook对象模型里的顶层对象(这点和Word和Excel是一样的)。在VSTO项目中要获得该对象的实例同样可以通过ThisAddIn类的Application字段来实现,具体代码为:Globals.ThisAddIn.Application或This.Application
2.2 NameSpace对象
Application对象的Session属性返回一个NameSpace对象,Session从字面上看是会话的意思,在Web开发中,我们可以从Session对象中获得保存的信息,同样,我们可以通过NameSpace对象来访问Outlook数据,比如当我们想获得收件箱里邮件数量时,此时就可以用到NameSpace对象,具体代码如下:
- // 获得收件箱文件夹
- Outlook.MAPIFolder Inbox =this.Application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
- // 获得收件箱中邮件数量
- int mailnumbers = Inbox.Items.Count;
2.3 Explorer对象
Explorer对象是显示Outlook中文件夹内容的窗口。文件夹包含项,例如邮件项,通俗点说,我们点击Outlook中的邮件或日历或联系人时,出现的窗口就是一个Explorer对象。
2.4 Inspector对象
Inspector对象是显示Outlook中每个项(例如单个电子邮件项、单个联系人项)的窗口。看到这里,有些朋友肯定会把Explorer对象与Inspector对象弄混淆,相信通过下面的图大家肯定可以完全明白两者的区别:
2.5 Outlook文件夹,即MAPIFolder对象
Outlook文件夹用来存储项(即邮件项,联系人项,任务项等),在Outlook中你可以创建自己的文件夹,然而Outlook中也提供了一些默认的文件夹。上面的这段代码: this.Application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox); 就是获得收件箱文件夹,如果你需要获得其他文件夹,可以通过改变OlDefaultFolders枚举值来获得。
2.6 Outlook项
Outlook里的项包含在文件夹里的。我们可以通过下面的代码来创建一个邮件项,如果要获得其他的Outlook项,可以通过修改Outlook.OlItemType枚举值来实现
// 创建邮件项 Outlook.MailItem mailItem = (Outlook.MailItem)this.Application.CreateItem(Outlook.OlItemType.olMailItem);
三、自定义Outlook窗体
介绍了Outlook的这么多对象的,大家肯定很迫不及待地想知道使用VSTO的技术可以为Outlook实现什么样的功能呢?下面就用VSTO的技术来自定义Outlook的联系人窗体,在很多时候,我们都希望联系人的窗体中有关于父母的联系方式,然后在现有的Outlook界面中却没有这样的字段来给我们填写的,所以这里通过Form Region 的方式来实现自定义联系人窗体,我们需要在联系人窗体中加入输入父母姓名和联系方式的控件。
首先,我们需要创建Outlook窗体区域,创建步骤如下:
- 右键项目,选择添加——>新建项目——>Outlook窗体区域

- 选择”设计新的窗体区域“选项

3. 窗体区域类型选择相邻,即把自定义的窗体附加到页面的底部。
4. 为窗体区域输入一个名字,并且设定在编辑模和阅读模式和中都显示窗体区域。
5. 把我们的窗体区域嵌入在联系人窗体中。
完全以上一系列的步骤之后,VS会帮我们自动创建一个空的窗体区域,如果我们想修改刚才创建的窗体区域的设置,我们可以通过它的属性窗口中进行修改。
创建完窗体区域之后,我们就需要在窗体区域中添加我们需要自定义的控件了,这里的设计界面如下:
设计完界面之后,最后就是实现我们的后台逻辑了,即在后台写代码来完成我们所需要实现的功能。具体后台代码如下(因为代码注释中都有解释,大家不懂实现过程可以看代码注释):
- // 对应的联系人(Contact)对象
- private Outlook.ContactItem contactItem;
- // 自定义属性对象
- private Outlook.ItemProperty MotherName = null;
- private Outlook.ItemProperty MotherTelNumber = null;
- private Outlook.ItemProperty FatherName = null;
- private Outlook.ItemProperty FatherTelNumber = null;
- // 在显示窗体区域之前发生。
- // 使用 this.OutlookItem 获取对当前 Outlook 项的引用。
- // 使用 this.OutlookFormRegion 获取对窗体区域的引用。
- private
void ContactFormRegion_FormRegionShowing(object sender, System.EventArgs e) - {
- // 获得FormRegion所对应的Contact对象
- contactItem = this.OutlookItem as Outlook.ContactItem;
- // 在从自定义属性中取出值时,首先确保自定义属性不为空。
- EnsureProperties();
- // 从联系人的自定义属性中取出值为控件赋值
- txbMotherName.Text = MotherName.Value;
- txbFatherName.Text = FatherName.Value;
- txbMotherTel.Text = MotherTelNumber.Value;
- txbFatherTel.Text = FatherTelNumber.Value;
- }
- // 在关闭窗体区域时发生。
- // 使用 this.OutlookItem 获取对当前 Outlook 项的引用。
- // 使用 this.OutlookFormRegion 获取对窗体区域的引用。
- private
void ContactFormRegion_FormRegionClosed(object sender, System.EventArgs e) - {
- // 释放对象
- System.Runtime.InteropServices.Marshal.FinalReleaseComObject(contactItem);
- contactItem = null;
- }
- // 确保所有自定义属性不为空
- private
void EnsureProperties() - {
- EnsureItemProperty(ref MotherName, "montherName", Outlook.OlUserPropertyType.olText);
- EnsureItemProperty(ref FatherName, "fatherName", Outlook.OlUserPropertyType.olText);
- EnsureItemProperty(ref MotherTelNumber, "motherTelNumber", Outlook.OlUserPropertyType.olText);
- EnsureItemProperty(ref FatherTelNumber, "fatherTelNumber", Outlook.OlUserPropertyType.olText);
- }
- // 确保项目属性不为空引用
- private
void EnsureItemProperty(ref Outlook.ItemProperty property, string name, Outlook.OlUserPropertyType propertyType) - {
- // 如果自定义属性为空时
- // 首先从联系人项关联的属性集合中获得属性对象
- // 如果项目集合中还不存在该属性时,就把该属性名称添加进ItemProperties集合中
- if (property == null)
- {
- property = contactItem.ItemProperties[name];
- if (property == null)
- {
- property = contactItem.ItemProperties.Add(name, propertyType);
- }
- }
- }
- // 父亲名字修改事件
- private
void txbFatherName_TextChanged(object sender, EventArgs e) - {
- // 保存值到自定义的属性中
- FatherName.Value = txbFatherName.Text;
- }
- // 父亲的电话号码修改事件
- private
void txbFatherTel_TextChanged(object sender, EventArgs e) - {
- // 保存值到自定义的属性中
- FatherTelNumber.Value = txbFatherTel.Text;
- }
- // 母亲名字修改事件
- private
void txbMotherName_TextChanged(object sender, EventArgs e) - {
- // 保存值到自定义的属性中
- MotherName.Value = txbMotherName.Text;
- }
- // 母亲的电话号码修改事件
- private
void txbMotherTel_TextChanged(object sender, EventArgs e) - {
- // 保存值到自定义的属性中
- MotherTelNumber.Value = txbMotherTel.Text;
- }
从上面的代码中可以看出,主要的实现思路是——初始化联系人窗口,从自定义属性中获取值来初始化窗体中控件的值,如果自定义属性不存在时,此时就需要把自定义属性添加进ItemProperties集合中来确保自定义属性不为空,如果自定义属性存在,则直接中自定义属性中获取值来初始化窗体中的控件。最后注册窗体中每个控件的修改事件,把控件中值的修改保存到自定义属性中,这样以便下次打开联系人时可以获得修改过的数据。
这样我们的设计就完成了,接下来看看程序的运行结果吧(按F5 运行该程序):
运行出现的第一个窗口为:
点击新建联系人之后,出现编辑联系人窗体,此时在窗体中可以看到我们自定义的窗体:
输入联系人的相关信息,点击保存并关闭按钮,然后我们再打开该联系人,修改"父亲电话"为 ”123456“(之前是123456789),点击保存并关闭按钮,当我们下次再打开该联系人时,此时可以获得修改后的数据信息:
这样就成功完成了我们开始所说的需求,当然这个还有很多不足的地方,比如没有对电话号码进行验证(如在电话号码文本框中输入中文或者不存在的号码,或者不是11位的号码等情况进行讨论)。
VSTO学习(六)——创建Outlook解决方案的更多相关文章
- VSTO之旅系列(五):创建Outlook解决方案
原文:VSTO之旅系列(五):创建Outlook解决方案 本专题概要 引言 Outlook对象模型 自定义Outlook窗体 小结 一.引言 在上一个专题中,为大家简单介绍了下如何创建Word解决方案 ...
- VSTO学习笔记(一)VSTO概述
原文:VSTO学习笔记(一)VSTO概述 接触VSTO纯属偶然,前段时间因为忙于一个项目,在客户端Excel中制作一个插件,从远程服务器端(SharePoint Excel Services)上下载E ...
- VSTO学习(五)——创建Word解决方案
一.引言 在上一个专题中主要为大家介绍如何自定义我们的Excel 界面的,然而在这个专题中,我将为大家介绍如何用VSTO来创建Word项目,对于Word的VSTO开发和Excel的开发很类似,你同样也 ...
- VSTO之旅系列(二):创建Excel解决方案
原文:VSTO之旅系列(二):创建Excel解决方案 本专题概要 引言 创建VSTO项目 Excel对象模型 创建Excel外接程序 创建Excel文档级自定义项 小结 一.引言 也许很多朋友都没有听 ...
- VSTO 学习笔记(六)在 Excel 2010中使用RDLC报表
原文:VSTO 学习笔记(六)在 Excel 2010中使用RDLC报表 Excel具有强大的图表显示.分析功能,这点毋庸置疑,但是如果将常规MIS系统中的数据以报表的形式在Excel中显示,却并不那 ...
- VSTO之旅系列(四):创建Word解决方案
原文:VSTO之旅系列(四):创建Word解决方案 本专题概要 引言 Word对象模型 创建Word外接程序 小结 一.引言 在上一个专题中主要为大家介绍如何自定义我们的Excel 界面的,然而在这个 ...
- VSTO学习笔记(二)Excel对象模型
原文:VSTO学习笔记(二)Excel对象模型 上一次主要学习了VSTO的发展历史及其历代版本的新特性,概述了VSTO对开发人员的帮助和效率提升.从这次开始,将从VSTO 4.0开始,逐一探讨VSTO ...
- VSTO学习笔记(十四)Excel数据透视表与PowerPivot
原文:VSTO学习笔记(十四)Excel数据透视表与PowerPivot 近期公司内部在做一种通用查询报表,方便人力资源分析.统计数据.由于之前公司系统中有一个类似的查询使用Excel数据透视表完成的 ...
- VSTO 学习笔记(十二)自定义公式与Ribbon
原文:VSTO 学习笔记(十二)自定义公式与Ribbon 这几天工作中在开发一个Excel插件,包含自定义公式,根据条件从数据库中查询结果.这次我们来做一个简单的测试,达到类似的目的. 即在Excel ...
随机推荐
- 2018.08.17 洛谷P3110 [USACO14DEC]驮运(最短路)
传送门 一道sb最短路,从两个起点和终点跑一边最短路之后直接枚举两人的汇合点求最小值就行了. 代码: #include<bits/stdc++.h> #define N 40005 #de ...
- 2018.07.20 atcoder Largest Smallest Cyclic Shift(贪心)
传送门 题意:给你x个a,y个b,z个c,显然这些字符可以拼成若干字符串,然后求这些字符串中最小表示法表示出来的最大的那一个. 解法:贪心思想,用multiset维护现在拼成的字串,每次取一个最小的和 ...
- Spring3.x错误--Pointcut is not well-formed:expecting 'name pattern' at...
Spring3.x错误: 解决方法: (*com.dayang.service..*(..)) *和com.dayang.之间有空格
- post同步请求
// http://api.hudong.com/iphonexml.do?type=focus-c //post请求中url不带请求参数,请求参数在参数HTTPBody中设置, 需要创建可变 ...
- Activity生命流程
做Android的同学说起 Activity,那绝对是熟悉的不能再熟悉了,但是越熟悉的东西往往越陌生.我们真的了解她吗?她是我们所认识的那样吗?或许是,或许不是!了解与否, 让我们往下看.首先借And ...
- eclipse/myeclipse介绍
eclipse更加纯净,比较简洁,需要某些插件的时候,需要自己去配置才可以,而myeclipse自带了很多的插件功能更为强大. 在eclipse于myeclipse创建的项目是有差异的,eclipse ...
- [翻译]NUnit---Range and Repeat Attributes(十五)
RangeAttribute (NUnit 2.5) Range特性用于为参数话测试方法的参数的值范围指定一个值,与Random特性一样,NUnit会将每个参数的值组合为一些了测试用例,所以如果为一个 ...
- 设计模式之状态模式(State Pattern)
一.什么是状态模式? 把所有动作都封装在状态对象中,状态持有者将行为委托给当前状态对象 也就是说,状态持有者(比如汽车,电视,ATM机都有多个状态)并不知道动作细节,状态持有者只关心自己当前所处的状态 ...
- 数据帮助类(DataHelper)
/// <summary> /// 是否为空... /// </summary> /// <param name="str">数据值</p ...
- .Net Core + NGINX跳转登录时端口丢失
使用.Net Core + NGINX部署到服务器的时候,如果端口不是使用默认的80端口,在跳转到登录页面时,URL中的端口丢失. NGINX的配置如下: server { listen ; loca ...