如何选择不在资源管理器CurrentView中的MailItem

时间:2019-01-23 18:36:31

标签: c# outlook-addin

当尝试以编程方式选择要在ActiveExplorer中显示的MailItem时,出现“无法选择或取消选择该项目,因为它在当前视图中不可用”例外。

我在Outlook中有一个TaskPane,它根据用户指定的搜索条件显示电子邮件列表,并且我试图允许用户右键单击单个电子邮件(在TaskPane中)并在“资源管理器”窗口中显示它。当用户当前在资源管理器中打开/选择收件箱并且试图显示在收件箱中找到的电子邮件时,此功能非常有用。但是,如果他们尝试显示在已发送框中找到的电子邮件,则会引发“无法选择或取消选择该项目,因为该项目在当前视图中不可用”例外。

我通过将ActiveExplorer.CurrentFolder属性设置为所选电子邮件的父文件夹来更新视图,这似乎是最好的方法。我确认CurrentFolder和CurrentView属性已更改为应有的状态,并且Explorer视图的确发生了更改,但是当我尝试选择该项目时仍然遇到异常。

我最初只是尝试更改CurrentFolder,然后更改AddToSelection,但是将AddToSelection移到了一个事件处理程序,认为它发生得很快。当然,这并不能解决问题。

    public void SetExplorerSelection(string emailID)
    {

        //Get Outlook namespace
        var oApp = Globals.ThisAddIn.Application;
        var oNS = oApp.GetNamespace("mapi");

        //Get the Active Explorer
        Microsoft.Office.Interop.Outlook.Explorer activeExplorer = oApp.ActiveExplorer();

        //Clear the current selection
        activeExplorer.ClearSelection();

        //Get the Mail Item
        MailItem mailItem = oNS.GetItemFromID(emailID);

        if (activeExplorer.IsItemSelectableInView(mailItem))
        {
            //Show the item in the Explorer
            activeExplorer.AddToSelection(mailItem);

            return;
        }
        else
        {

            //* indicates items that were added to TRY to fix the problem

            //*Send selected item to public var
            currentMail = mailItem;

            //*Get the Current View
            Microsoft.Office.Interop.Outlook.View cView = activeExplorer.CurrentView;

            //*Check the initial states of CurrentFolder and CurrentView
            Debug.Print("Folder (from): " + activeExplorer.CurrentFolder.Name);
            Debug.Print("View (from): " + cView.Name);

            //*Create event handler for ViewSwitch
            activeExplorer.ViewSwitch += new ExplorerEvents_10_ViewSwitchEventHandler(Explorer_ViewSwitch);

            //Change the Current Folder being viewed in the Explorer
            activeExplorer.CurrentFolder = mailItem.Parent as Microsoft.Office.Interop.Outlook.Folder;

            //*Reset/Apply changes to the CurrentView
            cView = activeExplorer.CurrentView;
            cView.Reset();
            cView.Apply();

            //activeExplorer.AddToSelection(mailItem);

        }


    }

    //*ViewSwitch Event Handler
    public void Explorer_ViewSwitch()
    {

        //Get Outlook namespace
        var oApp = Globals.ThisAddIn.Application;
        var oNS = oApp.GetNamespace("mapi");

        //Get the ActiveExplorer
        Microsoft.Office.Interop.Outlook.Explorer activeExplorer = oApp.ActiveExplorer();

        //Get the CurrentView
        Microsoft.Office.Interop.Outlook.View cView = activeExplorer.CurrentView;

        //Check the current states of CurrentFolder and CurrentView
        Debug.Print("Folder (to): " + activeExplorer.CurrentFolder.Name);
        Debug.Print("View (to): " + cView.Name);

        //Add the item to the selection
        //***This is where the exception occurs***
        activeExplorer.AddToSelection(currentMail);

        //Reset the public var
        currentMail = null;

    }

正如我提到的,我确认调试显示正确的信息(从收件箱切换到已发送的框),并且在获取异常之前在资源管理器中更改了视图本身(选择了“已发送邮件”文件夹)。如果我已继续运行代码并由于视图已设置为“已发送”框而再次尝试使用同一封电子邮件,则它可以正常工作并正确提取已发送的电子邮件。

1 个答案:

答案 0 :(得分:0)

尝试此代码

public void SetExplorerSelection(string emailID)
{

    //Get Outlook namespace
    var oApp = Globals.ThisAddIn.Application;
    var oNS = oApp.GetNamespace("mapi");

    //Get the Active Explorer
    Microsoft.Office.Interop.Outlook.Explorer activeExplorer = oApp.ActiveExplorer();

    //Clear the current selection
    activeExplorer.ClearSelection();

    //Get the Mail Item
    try
    {
        MailItem mailItem = oNS.GetItemFromID(emailID);

        if (activeExplorer.IsItemSelectableInView(mailItem))
        {
            //Show the item in the Explorer
            activeExplorer.AddToSelection(mailItem);

            return;
        }
        else
        {
            int flag = 0;
            foreach(Microsoft.Office.Interop.Outlook.MAPIFolder myDestFolder in oNS.Folders[mailItem.ReceivedByName].Folders)
            {
                activeExplorer.CurrentFolder = myDestFolder;
                foreach (Microsoft.Office.Interop.Outlook.View tmp in myDestFolder.Views)
                {
                    try
                    {
                        activeExplorer.CurrentView = tmp;
                        activeExplorer.ClearSelection();
                        activeExplorer.AddToSelection(item);

                        tmp.Reset();
                        tmp.Apply();

                        flag = 1;
                        break;
                    }
                    catch
                    {
                        continue;
                    }
                }

                if(flag ==1 )
                    break;
            }

        }
    }
    catch
    {
        MessageBox.Show("It is deleted message");
    }

}

谢谢