WindowlessControls Tutorial - Part 4: Data Binding (continued)


After rereading my previous post about data binding, I don't feel that my sample does justice to the overall flexibility/utility of WindowlessControls. So, I decided to write another sample: a template for a Windows Mobile contact list application.

Let's start out by deciding the basic behavior of the Contact List:

  • The contact list should show the name on the left of the item, and the contacts number below it.
  • The contact's picture will be to the right of the name and number.
  • When the contact is selected, it should expand and show the street address and email address.

Like the previous example, we populate our ItemsControl with the data we want to bind. To get the list of Pocket Outlook contacts, access the handy OutlookSession class:

myItemsControl.ContentPresenter = typeof(ContactPresenter);
myItemsControl.Control = new StackPanel();

OutlookSession session = new OutlookSession();
foreach (Contact contact in session.Contacts.Items)
if (contact.Picture != null)

Now, let's set up the IInteractiveContentPresenter that will represent a contact. This ContactPresenter is a bit more complex than the previous Image Gallery example:

public class ContactPresenter : StackPanel, IInteractiveContentPresenter
// selection state rectangle
WindowlessRectangle myRectangle = new WindowlessRectangle();
// contact picture
WindowlessImage myImage = new WindowlessImage();

// obvious properties
WindowlessLabel myName = new WindowlessLabel(string.Empty, WindowlessLabel.DefaultBoldFont);
WindowlessLabel myNumber = new WindowlessLabel();
WindowlessLabel myAddress = new WindowlessLabel();
WindowlessLabel myEmail = new WindowlessLabel();
// this panel will house the email and address, and only be visible when focused
StackPanel myExtendedInfo = new StackPanel();

public ContactPresenter()
OverlayPanel overlay = new OverlayPanel();

// stretch to fit
overlay.HorizontalAlignment = WindowlessControls.HorizontalAlignment.Stretch;
overlay.VerticalAlignment = VerticalAlignment.Stretch;

// dock the picture to the right and the info to the left
DockPanel dock = new DockPanel();
StackPanel left = new StackPanel();
left.Layout = new DockLayout(new LayoutMeasurement(0, LayoutUnit.Star), DockStyle.Left);
myImage.Layout = new DockLayout(new LayoutMeasurement(0, LayoutUnit.Star), DockStyle.Right);
myImage.MaxHeight = 100;
myImage.MaxWidth = 100;

// 5 pixel border around the item contents
dock.Margin = new Thickness(5, 5, 5, 5);

// make the overlay fit the dock, so as to limit the size of the selection rectangle
overlay.FitWidthControl = overlay.FitHeightControl = dock;

// set up the rectangle color and make it fill the region
myRectangle.Color = SystemColors.Highlight;
myRectangle.HorizontalAlignment = WindowlessControls.HorizontalAlignment.Stretch;
myRectangle.VerticalAlignment = VerticalAlignment.Stretch;
// the rectangle does not paint by default
myRectangle.PaintSelf = false;

// add the extended info that is only visible when focused
StackPanel nameAndNumber = new StackPanel();
myExtendedInfo.Visible = false;

// set up the left side

// add the foreground and the background selection

// add the item

// this is the bottom border
WindowlessRectangle bottomBorder = new WindowlessRectangle(Int32.MaxValue, 1, Color.Gray);

#region IInteractiveStyleControl Members

public void ApplyFocusedStyle()
// make the rectangle paint to denote that it is focused
myRectangle.PaintSelf = true;
myExtendedInfo.Visible = true;

public void ApplyClickedStyle()


#region IContentPresenter Members

Contact myContact;
public object Content
return myContact;
// populate the various UI elements with the contact
myContact = value as Contact;
if (myContact.Picture != null)
myImage.Bitmap = new StandardBitmap(new Bitmap(myContact.Picture));

myName.Text = myContact.FileAs;
if (!string.IsNullOrEmpty(myContact.MobileTelephoneNumber))
myNumber.Text = myContact.MobileTelephoneNumber;
myNumber.Text = myContact.HomeTelephoneNumber;

myAddress.Text = string.Format("{0}\n{1} {2} {3}", myContact.HomeAddressStreet, myContact.HomeAddressCity, myContact.HomeAddressState, myContact.HomeAddressPostalCode);
myEmail.Text = myContact.Email1Address;


And the results of this tutorial can be seen in the video below.

This took me about 30 minutes to whip together, with a bit more time, this could easily be turned into a real Contact List application! Click here for the updated source code to this tutorial.