VSTO offers a number of classes to access Outlook information, but these classes do not implement IEnumerable<T> and are therefore not useable in a LINQ expression.
I wanted to be able to search for appointments using LINQ and write code that looks like this:
var appointments = new Appointments();
var selectedAppointments = from appointment in appointments
where appointment.Start <= end // end is parameter
&& appointment.End >= start // start is parameter
&& appointment.Categories.Contains("Billable")
orderby appointment.Start
select appointment;
To do this I converted the Items collection in an Outlook Folder to an IEnumerable<Outlook._AppointmentItem>.
The code for the Appointments class looks like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Outlook = Microsoft.Office.Interop.Outlook;
namespace Develop_One.OBiOne
{
/// <summary>
/// Class to wrap a collection of Outlook.Items as an IEnumerable of Outlook._AppointmentItem.
/// Doing this allows you to write LINQ queries against the Appointments.
/// </summary>
internal class Appointments : IEnumerable<Outlook._AppointmentItem>
{
private Outlook.Items _items;
/// <summary>
/// Default constructor will use the items in the default Calendar folder to initialize items collection.
/// </summary>
internal Appointments()
{
var app = new Outlook.ApplicationClass();
var cal = app.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar);
_items = cal.Items;
}
#region IEnumerable<_AppointmentItem> Members
public IEnumerator<Outlook._AppointmentItem> GetEnumerator()
{
// use the private AppointmentsEnumerator.
return new AppointmentsEnumerator(this._items);
}
#endregion
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
#endregion
private class AppointmentsEnumerator : IEnumerator<Outlook._AppointmentItem>
{
private System.Collections.IEnumerator _items;
internal AppointmentsEnumerator(Outlook.Items items)
{
_items = items.GetEnumerator();
}
#region IEnumerator<_AppointmentItem> Members
public Outlook._AppointmentItem Current
{
get
{
return (Outlook._AppointmentItem)_items.Current;
}
}
#endregion
#region IDisposable Members
public void Dispose()
{
return;
}
#endregion
#region IEnumerator Members
object System.Collections.IEnumerator.Current
{
get
{
return (Outlook._AppointmentItem)_items.Current;
}
}
public bool MoveNext()
{
bool result = _items.MoveNext();
while (_items.Current is Outlook._AppointmentItem == false && result == true)
{
result = _items.MoveNext();
}
return result;
}
public void Reset()
{
_items.Reset();
}
#endregion
}
}
}