Bubuhubu
Bubuhubu

Reputation: 81

Unable to cast object of type 'System.String' to type 'Microsoft.Office.Interop.Outlook.Store

I am developing Outlook add-ins which populates all the available shared mailboxes in to combo box and sends email using the selected mailbox.

When I select the mail account from combo box, I get error

Unable to cast object of type 'System.String' to type 'Microsoft.Office.Interop.Outlook.Store'

Following is the code. Populate combo box.

private void MailBoxOptions_Load(object sender, EventArgs e)
{
    Microsoft.Office.Interop.Outlook.Application application =
        new Microsoft.Office.Interop.Outlook.Application();
    Microsoft.Office.Interop.Outlook.NameSpace ns = application.GetNamespace("MAPI");
    Stores stores = ns.Stores;
    foreach (var store in Globals.ThisAddIn.Application.Session.Stores
        .Cast<Microsoft.Office.Interop.Outlook.Store>()
        .Where(c => c.ExchangeStoreType == 
                      Microsoft.Office.Interop.Outlook.OlExchangeStoreType.olExchangeMailbox))
    {
        if (store != null)
        {
            mailBoxes.Items.Add(store.DisplayName);
        }
        else
        {
            MessageBox.Show("You don't have access to any shared mail-inbox.");
        }
    }
}

Code for Combo box

public void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
    var selectedStore = (Store)mailBoxes.SelectedItem;

}

Any help would be appreciated. Thanks.

Upvotes: 0

Views: 1076

Answers (3)

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112752

With mailBoxes.Items.Add(store.DisplayName); you are adding the display name of the store as string to the ComboBox. And that's exacly what you get in return with mailBoxes.SelectedItem. Of course you cannot cast this string to Store.

You could wrap the store in a display class

public class StoreDisplay
{
    public StoreDisplay(Store store)
    {
        this.Store = store;
    }

    public Store Store { get; }

    public override string ToString() ==> Store.DisplayName;
}

Then you can add items to the ComboBox with

mailBoxes.Items.Add(new StoreDisplay(store));

Because ToString has been overridden, the ComboBox will show the DisplayName or every store item.

Finally, you can retrive the store with

var selectedStore = ((StoreDisplay)mailBoxes.SelectedItem)?.Store;
if (selectedStore != null) {
    ...
}

You can also try to add the Store objects directly to the ComboBox; however, I don't know if they will display correctly.


A side note: If you have conflicting type names or if you simply want shorter namespace references, you can use namespace aliases

using MsOl = Microsoft.Office.Interop.Outlook;
using AppSession = Globals.ThisAddIn.Application.Session;

and use it like this

var application = new MsOl.Application();
MsOl.NameSpace ns = application.GetNamespace("MAPI");
Stores stores = ns.Stores;
foreach (var store in AppSession.Stores
    .Cast<MsOl.Store>()
    .Where(c => c.ExchangeStoreType == MsOl.OlExchangeStoreType.olExchangeMailbox))
{
    ...
}

Upvotes: 1

IDarkCoder
IDarkCoder

Reputation: 709

I'm assuming mailBoxes is your ComboBox then

mailBoxes.Items.Add(store.DisplayName);

Only adds the DisplayName-strings to the ComboBox. Your problem now is to turn those back into the mailbox.
In case there cannot be two mailboxes with the same name I suggest a Dictionary

private Dictionary<string, Store> storeDictionary = new Dictionary<string, Store>();

private void MailBoxOptions_Load(object sender, EventArgs e)
{
    Microsoft.Office.Interop.Outlook.Application application = new Microsoft.Office.Interop.Outlook.Application();
    Microsoft.Office.Interop.Outlook.NameSpace ns = application.GetNamespace("MAPI");
    Stores stores = ns.Stores;
    foreach (var store in Globals.ThisAddIn.Application.Session.Stores.Cast<Microsoft.Office.Interop.Outlook.Store>().Where(c => c.ExchangeStoreType == Microsoft.Office.Interop.Outlook.OlExchangeStoreType.olExchangeMailbox))
    {
        if (store != null)
        {
            mailBoxes.Items.Add(store.DisplayName);
            storeDictionary.Add(store.DisplayName, store); // Add the items to the dictionary
        }
        else
        {
            MessageBox.Show("You don't have access to any shared mail-inbox.");
        }
    }
}

Then get the Store from the Dictionary

public void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
    if(!mailBoxes.SelectedItem is string selectedString))
        return;

    bool successful = storeDictionary.TryGetValue(selectedString, out Store selectedStore);
    if(!successful)
    {
        return;
    }
    // Access selectedStore here
}

Upvotes: 0

Matt.G
Matt.G

Reputation: 3609

if you can access Globals.ThisAddIn.Application.Session.Stores.Cast<Microsoft.Office.Interop.Outlook.Store>() .Where(c => c.ExchangeStoreType == Microsoft.Office.Interop.Outlook.OlExchangeStoreType.olExchangeMailbox) in comboBox1_SelectedIndexChanged,

you could try:

var selectedStore = Globals.ThisAddIn.Application.Session.Stores.Cast<Microsoft.Office.Interop.Outlook.Store>()
   .Where(c => c.ExchangeStoreType == Microsoft.Office.Interop.Outlook.OlExchangeStoreType.olExchangeMailbox)
   .SingleOrDefault(x => x.DisplayName == mailBoxes.SelectedItem);

Upvotes: 0

Related Questions