Restricting ContactsCollection by ItemId?

So if you’re working with Microsoft’s new Microsoft.WindowsMobile.PocketOutlook namespace and trying to use the OutlookCollection.Restrict method to filter by a Contact‘s (or any PimItem‘s) ItemId field, you will likely run into a problem.


First, let me say the ItemID Class sucks.  It exposes basically nothing useful but a ToString() method, even though it holds numeric data.  And the first item added to POOM gets the ItemId of 0x80000001, which you might note is an *unsigned* number (again, the CLS is a pain for not allowing unsigned numbers).  So if you have an ItemId class and you want to use it, you have to do something like this:


unchecked
{
    int myId = int
.Parse(m_outlookSession.Contacts.Items[0].ItemId.ToString())
}


Really, that’s how you have to do it.


So, let’s say we have a Contact’s ItemId and we want to see if the current session has said Contact.  One might try this:


m_outlookSession.Contacts.Items.Restrict(“[ItemId]=” + itemId.ToString());


A nice try, but that gives you the not-so-helpful exception:


The query string is incorrectly formatted.
Parameter name: [ItemId]=-2147483647


Alright, so ItemId only exposes itself as a string, and Restrict has little in the way of useful documentation or samples, so maybe we can try it as a string like so:


m_outlookSession.Contacts.Items.Restrict(“[ItemId]='” + itemId.ToString() + “’“);


Well that gives a similar exception, just adding the single quotes:


The query string is incorrectly formatted.
Parameter name: [ItemId]=-‘2147483647’


Because I’ve used POOM from C++, I know that ItemId seems new to me, so just as a lark I figure I’ll try ‘Oid’ as a field name instead, and keep it as a numeric:


m_outlookSession.Contacts.Items.Restrict(“[Oid]=” + itemId.ToString());


Lo and behold, success!


Now technically this might not be a true bug, but it’s sure not documented anywhere, nor would it be at all intuitive to guess if you’d not used C++ to access an IContact (which exports an Oid field, *not* an ItemId) before.  Bad Windows Mobile Team.  BAD!


Things needed:



  • The ItemID needs to have an explicit operator for conversion to an int at the very least.  A ToInt32 or ToIntPtr or something of the sort would be useful.
  • Either name the field Oid like it’s stored in the database, or provide some sort of substitution so when I filter by ItemId the underlying class converts that to Oid.
  • The least they could have done was give exception text like “The field cannot be found in the collection“
  • Documenting how to remove a Restrict once set would be useful (I used Restrict(“[Oid]<>0“) for lack of any better idea)

4 thoughts on “Restricting ContactsCollection by ItemId?”

  1. Thanks…this is exactly what i was looking for. CF2 seems so much better than CF1 in many regards, then they just blew it on some things. ItemID isn’t in the ContactProperty thing either…

    Like

  2. And that’s poor architecture. If ItemID can be a few different things, then the architects should have used polymorphism – after all that’s exatly what it’s for. ItemID should be a base class and then OID for Contacts and EntryID for Messages should derive from it. The I could determine the actual type at runtime and get methods like ToInt() for an OID.

    Thanks for the pointer on using the ctor as a filter.

    Like

  3. And to think I just spent the past 2 hrs bashing my head against the desk wondering why OutlookSession.Contacts.Items.Find wasn’t working with ItemId…

    Any idea on when they’re going to fix it?

    .NET cf SP2 perhaps?

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s