!!!!!!! This page has been updated for Silverlight 2 RTM : see post of Nov 18th (http://www.gleblanc.eu/Blog/post/Page-turner-updated-for-Silverlight-2-TRM.aspx) !!!!!
In this post, we'll turn pages, thanks to an outstanding component developed and made freely available by Mitsu Furuta of Microsoft France.
Turn the pages using the mouse, as if it was a book ! There are five paintings of Brueghel (a painter of 16th century) to be seen.
Project / source code
To add such a "page turner" into your Silverlight program, download the DLL that does the job. First, access the
project on Codeplex. The component was developed by Mitsu Furuta of Microsoft France. Incidentally, Mitsu is blogging in
French but also in
English.
Download the zip file, unzip it, compile the project in the
SLBookDemoApp directory and extract the
SLMitsuControls.dll file that is created by the compiler in the
ClientBin sub-directory.
The use of this component is under "Microsoft Public License" (MS-PL). I can read a computer book as if it was a novel but reading just a few paragraphs of lawyer's jargon always gives me headache. But here it's rather clear : you can use the component "as it is", even in commercial applications, royalty-free (I mean the component described here is royalty-free, not necessarily your application). Of course, you can't claim rights on this component... For me, it was obvious. Programmers and lawyers seem to have a brain somewhat different.
In your application, add a reference to the DLL you have just extracted and saved somewhere. In the UserControl tag in the xaml file, add :
xmlns:local="clr-namespace:SLMitsuControls;assembly=SLMitsuControls"
I chose local for future reference to the component but any name could be chosen.
Now, you need to add a component that has a visual appearence :
<local:UCBook x:Name="book" ..... />
where ..... can be replaced by any property you usually find in a component (Grid.Row, Canvas.Left, etc.).
Now, let's see the changes that have to be made in your Page.xaml.cs file. Your Page class must implement the IDataProvider interface (and consequently implement GetItem and GetCount functions). Some initialization (one line) has also to be done in the function that handles the Loaded event :
using SLMitsuControls;
.....
public partial class Page : UserControl,IDataProvider
{
.....
private void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
{
book.SetData(this);
}
public object GetItem(int index)
{
return pages.Items[index];
}
public int GetCount()
{
return pages.Items.Count;
}
.....
}
The images (here five) have to be mentionned in Grid.Resources (or Canvas.Resources, depending on the container) :
<Grid .... >
<Grid.Resources>
<ItemsControl x:Name="pages" >
<Image Source="Brueghel1.jpg" Stretch="UniformToFill" />
<Image Source="Brueghel2.jpg" Stretch="UniformToFill" />
<Image Source="Brueghel3.jpg" Stretch="UniformToFill" />
<Image Source="Brueghel4.jpg" Stretch="UniformToFill" />
<Image Source="Brueghel5.jpg" Stretch="UniformToFill" />
</ItemsControl>
</Grid.Resources>
....
</Grid>
The images (here 5 images, from Brueghel1.jpg to Brueghel5.jpg) need to be copied in the ClientBin directory (the directory of the xap file). This is often an overlooked step : adding the images in the project (as often done for images) doesn't help. The images need to be explicitly copied into the ClientBin directory.
To know which pages are visible, just handle the OnPageTurned event :
<local:UCBook x:Name="book" ..... OnPageTurned="book_OnPageTurned" />
.....
private void book_OnPageTurned(int leftPageIndex, int rightPageIndex)
{
.....
}
The leftPageIndex and rightPageIndex arguments get the value -1 when a page is not displayed (for instance there is no page at the left when the book is initially opened).
A page is not restricted to images : it could contain a set of components. Just replace the <Image ..... /> tag by any other tag, for instance a grid tag (container for all the elements of a page).