概述
我用VSTO创建了一个Outlook外接程序.外接程序有用于Mail.Compose带状类型的单个带状(视觉设计器)。带状选项卡ControlIdType设置为“自定义”。除设计器代码外,外接程序中唯一的代码是以下用于带状的Load处理程序。this.Context.CurrentItem意外地返回null。
代码
private void RibbonComposeMail_Load(object sender, RibbonUIEventArgs e)
{
try
{
var inspector = this.Context as Outlook.Inspector;
if (inspector == null)
{
throw new ApplicationException("Fail - Step 1");
}
var currentMailItem = inspector.CurrentItem as Outlook.MailItem;
if (currentMailItem == null)
{
throw new ApplicationException("Fail - Step 2");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}步骤
inspector.CurrentItem为空。备注
ControlidType很重要。“自定义”将导致问题,但默认的"Office“选项不会显示问题。Mail.Read的结果是相同的,前提是打开顺序反转到收件箱>草案>收件箱(失败)。Marshal.ReleaseComObject和inspector对象上调用currentMailItem的所有可能排列都没有区别。发布于 2013-09-16 02:13:45
迈克的评论帮助我发现了一些关于这种行为的更多的好奇。在步骤1中,只调用一次RibbonComposeMail_Load事件。但在第三步,它被称为两次。在步骤3第一次调用事件时,this.Context.CurrentItem为null,但第二次调用事件时,该属性将保存电子邮件。
它将NewInspector事件中的项值与带状Load事件中的项值进行比较,这使我注意到了这一点。因为步骤3的事件顺序是:Ribbon_Load、NewInspector、Ribbon_Load。我把Ribbon_Load拿到了MessageBox.Show,这是ThisAddIn.CurrentMailItem邮件的主题,但很惊讶地看到它是以前电子邮件打开的主题,也就是步骤2中的收件箱电子邮件!
结果是,如果Ribbon_Load事件为null,则解决方案是忽略this.Context.CurrentItem事件中的所有内容,因为第二个Ribbon_Load事件将以正确的值被触发。为什么我们在我的例子的第三步中看到这种奇怪的行为,而不是第一步呢?对于实现Outlook对象模型的人来说,这可能是一个问题。
发布于 2013-09-12 14:29:11
我自己也有同样的问题。
我设计了一个用于Outlook日历约会的带条条,我想在每次约会中保存一些额外的字段(例如“这次会议可以节省差旅吗?")
我成功了,但是,这很难做到。
正如您已经说过的,当您的Ribbon1_Load函数启动时,该Ribbon1_Load是空的.那么,您应该如何获得有关当前电子邮件消息或日历约会的详细信息?
这是你需要做的。这个例子是基于日历约会的,但是它很容易适应EmailItems。
首先,在ThisAddIn.cs文件中,您需要做一些更改:
public partial class ThisAddIn
{
Outlook.Inspectors inspectors;
public static Outlook.AppointmentItem theCurrentAppointment;
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
inspectors = this.Application.Inspectors;
inspectors.NewInspector += new Outlook.InspectorsEvents_NewInspectorEventHandler(Inspectors_NewInspector);
}当用户打开或创建一个新的Outlook项时,我们的"Inspectors_NewInspector“函数将被调用,此时,我们能够获得有关该项的详细信息:
void Inspectors_NewInspector(Microsoft.Office.Interop.Outlook.Inspector Inspector)
{
// This function (apparently) gets kicked off whenever a user opens a new or existing item
// in Outlook (Calendar appointment, Email, etc).
// We can intercept it, modify it's properties, before letting our Ribbon know about it's existance.
//
theCurrentAppointment = null;
object item = Inspector.CurrentItem;
if (item == null)
return;
if (!(item is Outlook.AppointmentItem))
return;
theCurrentAppointment = Inspector.CurrentItem as Outlook.AppointmentItem;
}有了这些代码之后,我们可以调整我们的Ribbon1_Load函数来接受这个"theCurrentAppointment“变量,并详细阅读用户正在创建/修改的日历约会。
private void Ribbon1_Load(object sender, RibbonUIEventArgs e)
{
// When this function gets called, "Globals.ThisAddIn.Application.ActiveInspector()" is always NULL, so we have
// to fetch the selected AppointmentItem via the ThisAddIn class.
if (ThisAddIn.theCurrentAppointment != null)
{
// Our Ribbon control contains a TextBox called "tbSubject"
tbSubject.Text = ThisAddIn.theCurrentAppointment.Subject
}
}发布于 2013-08-27 09:11:07
我不是百分之百确定,但听起来垃圾收集器已经清除了您的this.Context。
您能否尝试将您的上下文放在私有字段中并从中获取当前的内容:
private readonly Context _context = new Context();
private void RibbonComposeMail_Load(object sender, RibbonUIEventArgs e)
{
try
{
var inspector = _context as Outlook.Inspector;
if (inspector == null)
{
throw new ApplicationException("Fail - Step 1");
}
var currentMailItem = inspector.CurrentItem as Outlook.MailItem;
if (currentMailItem == null)
{
throw new ApplicationException("Fail - Step 2");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}如果这没有帮助,我通常使用Outlook.Application对象来获取当前的内容:
readonly Outlook._Application _application = new Outlook.Application();
var selectionList = _application.ActiveExplorer().Selection;
foreach (Object selObject in selectionList)
{
if (selObject is Outlook.MailItem)
{
var outlookMail = (selObject as Outlook.MailItem);
}
}或者,如果您只需要当前,正如在您的情况下所做的那样:
var mailItem = _application.ActiveExplorer().Selection[0];https://stackoverflow.com/questions/18458338
复制相似问题