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.
What’s more interesting in the demo:
Simulating Wrap Layout with RadDataBoundListBox
Building a custom control to be used for image holder
Using RadSlideView with SlideViewPictureSource
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.
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:
WrapViewModel : BaseModel
.image1 = value;
.image2 = value;
.image3 = value;
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:
.ItemIndex * 3;
.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.
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.
And the code behind looks like:
ImageLoaderControl : Control
DependencyProperty SourceProperty =
DependencyProperty RowIndexProperty =
DependencyProperty ColumnIndexProperty =
OnSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
ImageLoaderControl control = d
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:
Now we have the listbox with a simulate wrap layout and the fancy ImageLoaderControl to represent each image. Let’s see how to navigate to the slide view page upon a tap over an image:
sender, Telerik.Windows.Controls.ListBoxItemTapEventArgs e)
Image tappedImage = e.OriginalSource
ImageLoaderControl ownerControl = ElementTreeHelper.FindVisualAncestor<ImageLoaderControl>(tappedImage);
imageIndex = rowIndex * 3 + colIndex;
+ imageIndex, UriKind.RelativeOrAbsolute));
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.
The control’s usage is simple and straightforward:
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).
And the page’s code behind:
SlideViewPage : PhoneApplicationPage
// update selected index after layout is updated
// this is a bug in the BETA of RadSlideView
sender, EventArgs e)
.slideView.SelectedIndex = Int32.Parse(
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.