Building a Picture Browser app for Windows Phone using RadSlideView and RadDataBoundListBox

One of the fresh new add-ons for the official Q3 2011 release of RadControls for Windows Phone is RadSlideView. The control provides smooth and slick user experience allowing for navigating a sequence of content items slide-by-slide. The control is also fully aware of orientation changes and the items are resized and re-arranged accordingly to the current orientation.

In this post I want to demonstrate how easy it is to build a simple picture-browser application based on our RadDataBoundListBox and RadSlideView controls.

Simulating Wrap Layout with RadDataBoundListBox
Building a custom control to be used for image holder
Using RadSlideView with SlideViewPictureSource

App architecture

It is a very simple application with two pages – the main one that displays the list box with all the picture thumbnails. The second page contains a slide view instance and it is navigated to when a thumbnail image is tapped. Additional Tilt effect is used on each thumbnail to emphasize the user action. Embedded images are used on purpose, so that the application does not use your internet connection to download data. Still, the demo will work with any absolute or relative Uri.

Building the Wrap Layout

Currently our list box supports stack layout only. Our plans are to extend the control with a virtualized wrap layout that will have the same performance as the stack one and will allow you implement scenarios (like the one in this blog) for your apps. Although this feature is not yet available, we can easily simulate a wrap layout using stack layout with three inner images in each listbox item.

Here is how our view model looks like:

publicclassWrapViewModel : BaseModel

{

privateUri image1;

privateUri image2;

privateUri image3;

publicintItemIndex

{

get;

set;

}

publicUri Image1

{

get

{

returnthis.image1;

}

set

{

this.image1 = value;

this.OnPropertyChanged("Image1");

}

}

publicUri Image2

{

get

{

returnthis.image2;

}

set

{

this.image2 = value;

this.OnPropertyChanged("Image2");

}

}

publicUri Image3

{

get

{

returnthis.image3;

}

set

{

this.image3 = value;

this.OnPropertyChanged("Image3");

}

}

}

We have three Uri properties per item and each property will be bound to an Image control. The item index property is used to tell the index of this item in the owning source collection. This index will be used to determine the index of the contained images. For example:

intimage1Index = this.ItemIndex * 3;

intimage2Index = this.ItemIndex * 3 + 1;

Now that we have the view model we need to setup the item template in the listbox. It will consist of a grid layout with three columns and three custom ImageLoaderControl instances within each column.

Creating ImageLoaderControl

The control’s idea is to have two visual states – Loading and Loaded, indicating that an image is about to be displayed. Here is the control’s XAML:

The “Loading” state sets the “Loading…” text block’s visibility to Visible and the “Loaded” one hides the text block and displays the actual image. Of course this is a very simple scenario and you may implement more complex and visually appealing states to meet the requirements of you application.

We have a Source property, used to specify the source of the inner Image instance, a RowIndex property to tell the index of the container RadDataBoundListBoxItem and a ColumnIndex to specify the column (0, 1, 2) the control is located at. Upon a change in the Source property we enter the “Loaded” visual state, which hides the text block and displays the image. You may perform more complex logic here to determine when the “Loaded” state actually occurs by handling the ImageOpened event of the image.

The XAML of the main page is quite simple – it uses the image loader to setup its item itemplate:

We handle the ItemTap event of the listbox, find the owning ImageLoader control and navigate to the slide view page passing the currently selected index as a query string. And finally let’s see how the slide view page is setup.

We specify the special SlideViewPictureSource as its DataSource. The data source itself will provide a default item template, so no need to specify our own one except we want a more complex one rather than a simple Image. We bind the data source to the Images property of the main view model, which is actually a collection with the URIs of all the loaded images. Currently the picture data source does not support an ImageSource instance directly but it will when the control exits its BETA state and you will have even better support for images. We also have plans to add an arbitrary option to load images directly from the IsolatedStorage, based on specified folder(s).

Due to a bug that is currently present, the SelectedIndex property cannot be set before the control is added to the visual scene and its containers are created. That is why we handle the LayoutUpdated event of the page and specify the currently selected index of the control. The index is passed as a parameter in the page’s query string. Once the Service Pack of Q3 is out you will be able to bind the selected index to a property of the main view model.

Well, these are most of the more interesting parts of the demo app. I really hope that you will find it useful and learn some new tips and tricks from it. Do not hesitate to let me know for any suggestions or questions you may have.

Progress, Telerik, and certain product names used herein are trademarks or registered trademarks of Progress Software Corporation and/or one of its subsidiaries or affiliates in the U.S. and/or other countries. See Trademarks or appropriate markings.