Невозможно привести объект типа ‘System.Строка ‘для ввода’ Microsoft.Офис.Взаимодействие.Мировоззрение.Магазин

#c# #outlook-addin #office-addins

#c# #outlook-добавление #office-дополнения

Вопрос:

Я разрабатываю надстройки Outlook, которые заполняют все доступные общие почтовые ящики в поле со списком «Кому» и отправляют электронную почту с использованием выбранного почтового ящика.

Когда я выбираю учетную запись почты из поля со списком, я получаю сообщение об ошибке

Невозможно преобразовать объект типа ‘System.Строка’ для типа ‘Microsoft.Офис.Взаимодействие.Outlook.Сохранить’

Ниже приведен код. Заполните поле со списком.

 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.");
        }
    }
}
  

Код для поля со списком

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

}
  

Буду признателен за любую помощь.
Спасибо.

Комментарии:

1. Вы отладили свой код? Потому что существует так много применений типа store, которые не определяют, какой код отвечает за это.

Ответ №1:

С помощью mailBoxes.Items.Add(store.DisplayName); вы добавляете отображаемое название магазина как string в поле со списком. И это именно то, что вы получаете взамен mailBoxes.SelectedItem . Конечно, вы не можете преобразовать эту строку в Store .

Вы могли бы обернуть хранилище в класс отображения

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

    public Store Store { get; }

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

Затем вы можете добавлять элементы в поле со списком с помощью

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

Поскольку ToString он был переопределен, в выпадающем списке будет отображаться DisplayName или каждый элемент хранилища.

Наконец, вы можете повторно запустить хранилище с помощью

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

Вы также можете попробовать добавить Store объекты непосредственно в поле со списком; однако я не знаю, будут ли они отображаться правильно.


Дополнительное примечание: если у вас конфликтующие имена типов или вам просто нужны более короткие ссылки на пространство имен, вы можете использовать псевдонимы пространства имен

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

и использовать его следующим образом

 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))
{
    ...
}
  

Ответ №2:

Я предполагаю, что mailBoxes это ваш выпадающий список, тогда

 mailBoxes.Items.Add(store.DisplayName);
  

Добавляет только DisplayName -строки в поле со списком. Теперь ваша проблема заключается в том, чтобы вернуть их обратно в почтовый ящик.
В случае, если не может быть двух почтовых ящиков с одинаковым именем, я предлагаю 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.");
        }
    }
}
  

Затем получите Store из словаря

 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
}
  

Комментарии:

1. Привет, IDarkCoder, спасибо за ваш ответ. Теперь он показывает ошибку при mailBoxes.SelectedItem том, что Argument 1: cannot convert from 'object' to 'string'

2. Извините, я забыл преобразовать выбранный элемент в строку. Я соответствующим образом отредактировал свой ответ

3. Рад, что смог помочь. Не забудьте принять наиболее полезный ответ, установив флажок.

Ответ №3:

если вы можете получить доступ Globals.ThisAddIn.Application.Session.Stores.Cast<Microsoft.Office.Interop.Outlook.Store>()
.Where(c => c.ExchangeStoreType == Microsoft.Office.Interop.Outlook.OlExchangeStoreType.olExchangeMailbox)
в comboBox1_SelectedIndexChanged ,

вы могли бы попробовать:

 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);