I started working on a Silverlight Page Curl when I encountered one on the internet and realized I had not seen it done in Silverlight yet. Read the manual to learn how to customize the Silvelight Page Curl using intialization parameters.
A basic function is to use a small footprint for the plug-in and enlarging that to a new plug-in size. This way most of the original page can be used for content and links close to the plug-in can be clicked, while you can still show a good part of an image beneath the curl when the mouse cursor is hovered over the plug-in. The plug-in size has to be reduced again when the mouse cursor is outside the plug-in area.
The page curl is customized using initialization parameters on the plug-in:
<param name="initParams" value="
imageUrl=/images/SLPageCurl.jpg,
imageLink=http://antonidol.nl/pagecurl,
curlColor=#FFC4D8F8,
isCloseable=true
"/>
These are efficiently picked up and added to the Application Resources in a foreach loop in App.xaml.cs:
//Place initParams in Resources
foreach (var item in e.InitParams)
{
this.Resources.Add(item.Key, item.Value);
}
When retrieved, these are Strings and need to be converted before they can be used:
if (App.Current.Resources.Contains("imageUrl"))
{
imageUrl = new Uri(App.Current.Resources["imageUrl"].ToString(),
UriKind.Relative);
Image.Source = new BitmapImage(imageUrl);
Image.ImageFailed +=
new EventHandler<ExceptionRoutedEventArgs>(Image_ImageFailed);
}
In this case a default image should become visible when the image cannot be loaded. Remember, the path and filename come from the initParams, so they could be wrong. The ImageFailed event allows you to provide an alternative when the imageUrl setting doesn’t lead to a valid image:
void Image_ImageFailed(object sender, ExceptionRoutedEventArgs e)
{
imageUrl = new Uri("Images/SLPageCurlDefault.jpg", UriKind.Relative);
Image.Source = new BitmapImage(imageUrl);
}
To move the curl, animations XAML in are called. The plug-in size has to be altered by changing the style attributes on the SLPageCurlContainer DIV. The SetStyleAttribute in the HTML-bridge is the way to do that.
//grow
private void sizeUp(object sender, System.Windows.Input.MouseEventArgs e)
{
HtmlElement htmlEl =
HtmlPage.Document.GetElementById("SLPageCurlContainer");
htmlEl.SetStyleAttribute("height", "500px");
htmlEl.SetStyleAttribute("width" , "500px");
aniSizeUp.Completed += new EventHandler(aniSizeUp_Completed);
aniSizeUp.Begin();
}
When the plug-in is enlarged, the mouseEnter and mouseLeave events are triggered. This results is the Page Curl closing the second it is opened. Therefore it is necessary to add and remove the mouse events on the completed events of the animations that start, grow, shrink and close the page curl. This way animations cannot be triggered when they don’t have to.
void aniSizeUp_Completed(object sender, EventArgs e)
{
LayoutRoot.MouseEnter -= sizeUp;
LayoutRoot.MouseLeave += new MouseEventHandler(sizeDown);
}
Showing the image URL in the browser status bar also works via the HTML-bridge. With the System.Windows.Browser namespace in the page, you can access the status bar with the setProperty method. This takes a string for the name of the property and a value.
//show URL in Statusbar
private void showUrl(object sender, System.Windows.Input.MouseEventArgs e)
{
HtmlPage.Window.SetProperty("status", imageLink);
}
The isCloseable option, in combination with the internal Closed state offered some challenges because they interact with each other. Furthermore, because the setting is stored in Isolated Storage, it will not show again after it is closed. Only by setting the isCloseable initialization parameter to false and duplicating that value in the Closed Boolean internally, it is possible to make it visible again. Handy when debugging…
The Page Curl Manual is available online and the Silverlight application is available on my SkyDrive.
Njoy!