首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Outlook Inspector.CurrentItem为空

Outlook Inspector.CurrentItem为空
EN

Stack Overflow用户
提问于 2013-08-27 06:22:51
回答 3查看 6.6K关注 0票数 2

概述

我用VSTO创建了一个Outlook外接程序.外接程序有用于Mail.Compose带状类型的单个带状(视觉设计器)。带状选项卡ControlIdType设置为“自定义”。除设计器代码外,外接程序中唯一的代码是以下用于带状的Load处理程序。this.Context.CurrentItem意外地返回null。

代码

代码语言:javascript
复制
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);
    }
}

步骤

  1. 打开电子邮件草稿。丝带装好了。
  2. 从收件箱打开电子邮件。
  3. 打开相同的草稿电子邮件。丝带在第2步失败,inspector.CurrentItem为空。

备注

  • 我在Outlook 2007、2010和2013中测试了这一点,在VS2010中创建了Outlook 2007和2010外接程序,在VS2012中创建了Outlook 2010外接程序。所有的行为都一样。
  • 反复打开电子邮件草稿似乎不会导致问题,必须在中间打开Email.Read检查器。
  • 带状标签ControlidType很重要。“自定义”将导致问题,但默认的"Office“选项不会显示问题。
  • 翻转其头上的场景并将带状类型设置为Mail.Read的结果是相同的,前提是打开顺序反转到收件箱>草案>收件箱(失败)。
  • Marshal.ReleaseComObjectinspector对象上调用currentMailItem的所有可能排列都没有区别。
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-09-16 02:13:45

迈克的评论帮助我发现了一些关于这种行为的更多的好奇。在步骤1中,只调用一次RibbonComposeMail_Load事件。但在第三步,它被称为两次。在步骤3第一次调用事件时,this.Context.CurrentItem为null,但第二次调用事件时,该属性将保存电子邮件。

它将NewInspector事件中的项值与带状Load事件中的项值进行比较,这使我注意到了这一点。因为步骤3的事件顺序是:Ribbon_LoadNewInspectorRibbon_Load。我把Ribbon_Load拿到了MessageBox.Show,这是ThisAddIn.CurrentMailItem邮件的主题,但很惊讶地看到它是以前电子邮件打开的主题,也就是步骤2中的收件箱电子邮件!

结果是,如果Ribbon_Load事件为null,则解决方案是忽略this.Context.CurrentItem事件中的所有内容,因为第二个Ribbon_Load事件将以正确的值被触发。为什么我们在我的例子的第三步中看到这种奇怪的行为,而不是第一步呢?对于实现Outlook对象模型的人来说,这可能是一个问题。

票数 3
EN

Stack Overflow用户

发布于 2013-09-12 14:29:11

我自己也有同样的问题。

我设计了一个用于Outlook日历约会的带条条,我想在每次约会中保存一些额外的字段(例如“这次会议可以节省差旅吗?")

我成功了,但是,这很难做到。

正如您已经说过的,当您的Ribbon1_Load函数启动时,该Ribbon1_Load是空的.那么,您应该如何获得有关当前电子邮件消息或日历约会的详细信息?

这是你需要做的。这个例子是基于日历约会的,但是它很容易适应EmailItems。

首先,在ThisAddIn.cs文件中,您需要做一些更改:

代码语言:javascript
复制
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“函数将被调用,此时,我们能够获得有关该项的详细信息:

代码语言:javascript
复制
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“变量,并详细阅读用户正在创建/修改的日历约会。

代码语言:javascript
复制
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
     }
}
票数 4
EN

Stack Overflow用户

发布于 2013-08-27 09:11:07

我不是百分之百确定,但听起来垃圾收集器已经清除了您的this.Context。

您能否尝试将您的上下文放在私有字段中并从中获取当前的内容:

代码语言:javascript
复制
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对象来获取当前的内容:

代码语言:javascript
复制
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);
    }
}

或者,如果您只需要当前,正如在您的情况下所做的那样:

代码语言:javascript
复制
var mailItem = _application.ActiveExplorer().Selection[0];
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18458338

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档