is this a collection or not.

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

hey all,

Dim _oItems As Outlook.Items
Dim oInbox As Outlook.MAPIFolder =
oNS.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox)
_oItems = oInbox.Items


I can iterate thru this with a for-each loop however i cannot bind directly
to datagrid. Any ideas why not? or how i can get this in a datagrid.

thanks,
rodchar
 
rodchar,
To bind to a Windows DataGrid the collection needs to support IList or
IListSource (IListSource indirectly gives you an IList).

To bind to a Web DataGrid the collection needs to support IEnumerable (which
his what For Each uses). However you really should not be using Outlook from
a Web Form!

Outlook being a COM application does not know about the IList interface,
hence you cannot bind directly to it. You should be able to create a wrapper
class that implements IList that you can bind to, that simply delegates the
IList methods that it cares about to the underlying Outlook Items
collection.

Hope this helps
Jay
 
thanks for the reply...
Jay, may I ask for clarification (me being a novice to Windows development)

You should be able to create a wrapper
class that implements IList that you can bind to, that simply delegates the
IList methods that it cares about to the underlying Outlook Items
collection.


when you say that simply delegates IList methods that it cares about, could
you possibly give me a for instance scenario or a beginner analogy i can
relate to.

thanks,
rodchar
novice
 
Rodchar,

As Jay already wrote is the collection you are now iterating through is not
implementing IList.

So the easiest thing you can do in my opinion is first create a datatable
using a simple for each loop. Don't be afraid of the time, behind the scene
are this kind of loops made as well and go very fast.

\\\
dt as new datatable
dt.add.columns("firstcolumn")
dt.add.columns("nextcolumn")
for each outlookitem............. your iteration in the outlook collection
dim dr as datarow = dt.newrow
dr("firstcolumn) = outlookitem("whatever")
dr("nextcolumn) = outlookitem("nextwhatever")
next
datagrid1.datasource = dt
////

I hope this helps?

Cor
 
thanks...ok that helped...
but an issue came up while writing this.


dr.MailSubject = item.Subject.ToString
dr.MailReceiveTime = item.ReceivedTime.ToString


if i leave .ToString off the mail subject Outlook prompts me with 2 security
messages.

if i leave .ToString off the ReceiveTime I don't get those prompts.

Any ideas why?

thanks,
rodchar
 
rodchar,
Unfortunately to give you a quick sample that works, would require that I
charge you for 40+ hours of work... Using Cor's example of manually copying
the data into a dataset might be the easiest way, especially for a novice.
The other option might be to find a Grid (such as the "Microsoft Office
Outlook View Control") that displays Outlook data natively.

http://support.microsoft.com/search/default.aspx?qu=Outlook+View+Control

The problem with the wrapper & Cor's method is that you are going to get the
security prompt as it will appear you are harvesting addresses to send spam,
or worse virures, to your unsuspecting friends...

As I stated Outlook is firmly rooted in the COM world. .NET is the .NET
world, using Interop you can cross between these two worlds, largely
transparently which is great. .NET is based on Classes, where as COM is
based on Interfaces. When you define a variable of a COM object (such as
Outlook.Items) you are actually dealing with a RCW (Runtime Callable
Wrapper) that works closely with the COM interface of the COM object...

However! certain features, such as DataBinding require "full" .NET support.
It requires an actual Class to get the list of properties (fields) to show,
when you try to bind to Outlook (even with the wrapper) each item (row) is a
__ComObject (the RCW), these __ComObjects don't know about the properties
that Outlook is able to give, as Outlook can only return an Interface. To
get the wrapper to work the wrapper would need to implement the ITypedList
interface also, which allows the wrapper to return the list of properties
the object being bound to supports. Plus it would need to implement an
ItemWrapper also that is able to take the property from ITypedList & convert
it into an the respective Outlook property...


The other problem you are going to run into, when using any of the three
methods) is that the Outlook folders contain different types of Objects. For
example the inbox will contain Outlook.MailItem objects, plus
Outlook.MeetingItem if you got a meeting request, plus possibly a handful of
other types...


Here is a simply wrapper for the Outlook.Items collection.

NOTE: It does not work as the Grid cannot bind to the interfaces that
Outlook returns, that would require addition work:

Option Strict On
Option Explicit On

Imports Outlook = Microsoft.Office.Interop.Outlook

Public Class OutlookItemCollection
Implements IList

Private ReadOnly m_items As Outlook.Items
Private ReadOnly m_syncRoot As Object

Public Sub New(ByVal items As Outlook.Items)
m_items = items
End Sub

#Region " IList implementation "

Public Sub CopyTo(ByVal array As System.Array, ByVal index As Integer)
Implements System.Collections.ICollection.CopyTo
Throw New NotImplementedException
End Sub

Public ReadOnly Property Count() As Integer Implements
System.Collections.ICollection.Count
Get
Return m_items.Count
End Get
End Property

Public ReadOnly Property IsSynchronized() As Boolean Implements
System.Collections.ICollection.IsSynchronized
Get
Return False
End Get
End Property

Public ReadOnly Property SyncRoot() As Object Implements
System.Collections.ICollection.SyncRoot
Get
Return m_syncRoot
End Get
End Property

Public Function GetEnumerator() As System.Collections.IEnumerator
Implements System.Collections.IEnumerable.GetEnumerator
Return m_items.GetEnumerator()
End Function

Public Function Add(ByVal value As Object) As Integer Implements
System.Collections.IList.Add
m_items.Add(value)
End Function

Public Sub Clear() Implements System.Collections.IList.Clear
Throw New NotImplementedException
End Sub

Public Function Contains(ByVal value As Object) As Boolean Implements
System.Collections.IList.Contains
Throw New NotImplementedException
End Function

Public Function IndexOf(ByVal value As Object) As Integer Implements
System.Collections.IList.IndexOf
Throw New NotImplementedException
End Function

Public Sub Insert(ByVal index As Integer, ByVal value As Object)
Implements System.Collections.IList.Insert
Throw New NotImplementedException
End Sub

Public ReadOnly Property IsFixedSize() As Boolean Implements
System.Collections.IList.IsFixedSize
Get
Return False
End Get
End Property

Public ReadOnly Property IsReadOnly() As Boolean Implements
System.Collections.IList.IsReadOnly
Get
Return False
End Get
End Property

Default Public Property Item(ByVal index As Integer) As Object
Implements System.Collections.IList.Item
Get
Return m_items(index + 1)
End Get
Set(ByVal value As Object)
Throw New NotImplementedException
End Set
End Property

Public Sub Remove(ByVal value As Object) Implements
System.Collections.IList.Remove
Throw New NotImplementedException
End Sub

Public Sub RemoveAt(ByVal index As Integer) Implements
System.Collections.IList.RemoveAt
Throw New NotImplementedException
End Sub

#End Region

End Class

Hope this helps
Jay
 
thanks for the great help.

Jay B. Harlow said:
rodchar,
Unfortunately to give you a quick sample that works, would require that I
charge you for 40+ hours of work... Using Cor's example of manually copying
the data into a dataset might be the easiest way, especially for a novice.
The other option might be to find a Grid (such as the "Microsoft Office
Outlook View Control") that displays Outlook data natively.

http://support.microsoft.com/search/default.aspx?qu=Outlook+View+Control

The problem with the wrapper & Cor's method is that you are going to get the
security prompt as it will appear you are harvesting addresses to send spam,
or worse virures, to your unsuspecting friends...

As I stated Outlook is firmly rooted in the COM world. .NET is the .NET
world, using Interop you can cross between these two worlds, largely
transparently which is great. .NET is based on Classes, where as COM is
based on Interfaces. When you define a variable of a COM object (such as
Outlook.Items) you are actually dealing with a RCW (Runtime Callable
Wrapper) that works closely with the COM interface of the COM object...

However! certain features, such as DataBinding require "full" .NET support.
It requires an actual Class to get the list of properties (fields) to show,
when you try to bind to Outlook (even with the wrapper) each item (row) is a
__ComObject (the RCW), these __ComObjects don't know about the properties
that Outlook is able to give, as Outlook can only return an Interface. To
get the wrapper to work the wrapper would need to implement the ITypedList
interface also, which allows the wrapper to return the list of properties
the object being bound to supports. Plus it would need to implement an
ItemWrapper also that is able to take the property from ITypedList & convert
it into an the respective Outlook property...


The other problem you are going to run into, when using any of the three
methods) is that the Outlook folders contain different types of Objects. For
example the inbox will contain Outlook.MailItem objects, plus
Outlook.MeetingItem if you got a meeting request, plus possibly a handful of
other types...


Here is a simply wrapper for the Outlook.Items collection.

NOTE: It does not work as the Grid cannot bind to the interfaces that
Outlook returns, that would require addition work:

Option Strict On
Option Explicit On

Imports Outlook = Microsoft.Office.Interop.Outlook

Public Class OutlookItemCollection
Implements IList

Private ReadOnly m_items As Outlook.Items
Private ReadOnly m_syncRoot As Object

Public Sub New(ByVal items As Outlook.Items)
m_items = items
End Sub

#Region " IList implementation "

Public Sub CopyTo(ByVal array As System.Array, ByVal index As Integer)
Implements System.Collections.ICollection.CopyTo
Throw New NotImplementedException
End Sub

Public ReadOnly Property Count() As Integer Implements
System.Collections.ICollection.Count
Get
Return m_items.Count
End Get
End Property

Public ReadOnly Property IsSynchronized() As Boolean Implements
System.Collections.ICollection.IsSynchronized
Get
Return False
End Get
End Property

Public ReadOnly Property SyncRoot() As Object Implements
System.Collections.ICollection.SyncRoot
Get
Return m_syncRoot
End Get
End Property

Public Function GetEnumerator() As System.Collections.IEnumerator
Implements System.Collections.IEnumerable.GetEnumerator
Return m_items.GetEnumerator()
End Function

Public Function Add(ByVal value As Object) As Integer Implements
System.Collections.IList.Add
m_items.Add(value)
End Function

Public Sub Clear() Implements System.Collections.IList.Clear
Throw New NotImplementedException
End Sub

Public Function Contains(ByVal value As Object) As Boolean Implements
System.Collections.IList.Contains
Throw New NotImplementedException
End Function

Public Function IndexOf(ByVal value As Object) As Integer Implements
System.Collections.IList.IndexOf
Throw New NotImplementedException
End Function

Public Sub Insert(ByVal index As Integer, ByVal value As Object)
Implements System.Collections.IList.Insert
Throw New NotImplementedException
End Sub

Public ReadOnly Property IsFixedSize() As Boolean Implements
System.Collections.IList.IsFixedSize
Get
Return False
End Get
End Property

Public ReadOnly Property IsReadOnly() As Boolean Implements
System.Collections.IList.IsReadOnly
Get
Return False
End Get
End Property

Default Public Property Item(ByVal index As Integer) As Object
Implements System.Collections.IList.Item
Get
Return m_items(index + 1)
End Get
Set(ByVal value As Object)
Throw New NotImplementedException
End Set
End Property

Public Sub Remove(ByVal value As Object) Implements
System.Collections.IList.Remove
Throw New NotImplementedException
End Sub

Public Sub RemoveAt(ByVal index As Integer) Implements
System.Collections.IList.RemoveAt
Throw New NotImplementedException
End Sub

#End Region

End Class

Hope this helps
Jay
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top