Silverlight 2.0 might be all the fashion but 1.0 is released and out there, so there is value in using it purely for the wider reach and acceptance of users who are happier to install the released plugin.
So here is a easy little app you can write your self to give you an image rotator with click through and whatever logic you want for the weighting of the images.
It fits together as follows:
- A Silverlight Xaml page with some JavaScript to control it
- An Asp.Net web page with the Script manager from the Ajax Extensions
- A simple asmx web service that returns the next image to show.
The Silverlight Xaml
The following is a small bit of Xaml that has an image, a textblock and an storyboard that fades the image in and out using the opacity property:
<Canvas
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="420" Height="452"
Background="#00000000"
x:Name="Page" >
<Canvas.Resources>
<Storyboard x:Name="Storyboard1">
<DoubleAnimationUsingKeyFrames AutoReverse="True"
BeginTime="00:00:00" Storyboard.TargetName="image"
Storyboard.TargetProperty="(UIElement.Opacity)" >
<SplineDoubleKeyFrame KeyTime="00:00:01" Value="0"/>
<SplineDoubleKeyFrame KeyTime="00:00:03" Value="1"/>
<SplineDoubleKeyFrame KeyTime="00:00:04" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Canvas.Resources>
<Image Cursor="Arrow" Opacity="0" Width="420" Height="452"
x:Name="image" Canvas.Left="8" Source="images/viewdemo.png"/>
<TextBlock x:Name="textBlock1"></TextBlock>
</Canvas>
The Web Service
This is a simple asmx web service. Remember to mark it as a script service by adding the following attribute to the service class:
[System.Web.Script.Services.ScriptService]
You can do whatever you want in the web service of course. I decided to return a custom type called BannerImage with a few useful properties:
[WebMethod]
public BannerImage GetNextImageUrl(int lastId)
{
//of course in the final code this will return
//new details each time (from an xml file on the server perhaps)
return new BannerImage() { Url = "images/HappyPhonePeople.png",
NavigateUrl = http://www.bbc.co.uk,
ImageId=lastId+1 };
}
BannerImage looks like this:
public class BannerImage
{
public string Url { get; set; }
public string NavigateUrl { get; set; }
public int ImageId { get; set; }
}
The JavaScript
The JavaScript does all the work of controlling the interaction with the Silverlight Xaml and calling the web service. The code below hooks up various events and calls the web services as required (see the next section for detail on how the web service proxy was created)
if (!window.ImagesRotation)
ImagesRotation = {};
ImagesRotation.Page = function()
{
}
ImagesRotation.Page.prototype =
{
handleLoad: function(control, userContext, rootElement)
{
this.control = control;
this.storyboard1 = control.content.findName("Storyboard1");
this.image1 = control.content.findName("image");
this.textBlock1 = control.content.findName("textBlock1");
this.bannerImage = null;
this.GetNextImage(0);
this.storyboard1.addEventListener("Completed",
Silverlight.createDelegate(this, this.storyboard1Completed));
this.image1.addEventListener("MouseLeftButtonUp",
Silverlight.createDelegate(this, this.imageClick));
},
storyboard1Completed: function(sender, eventArgs)
{
var id = this.bannerImage.ImageId;
this.GetNextImage(id);
},
GetNextImage: function(id)
{
//BannerImages is the web service proxy created us by the
// scriptmanager when we add a service reference
BannerImages.GetNextImageUrl(id,Silverlight.createDelegate(this,this.onSuccess),
Silverlight.createDelegate(this,this.onFailure));
},
imageClick: function(sender, eventArgs)
{
location.href = this.bannerImage.NavigateUrl;
},
onSuccess: function(result)
{
this.bannerImage = result;
this.image1.source = this.bannerImage.Url;
if (this.bannerImage.NavigateUrl != "")
{
this.image1.cursor = "Hand";
}
else
{
this.image1.cursor = "Arrow";
}
this.storyboard1.Begin();
this.textBlock1.Text = this.bannerImage.ImageId.toString();
},
onFailure: function(result)
{
this.textBlock1.Text = "error: " + result.get_message();
}
}
The Aspx Page
The final piece is the Aspx page that hosts the Silverlight control and adds a client side service reference. First the ScriptManager. Here I have 3 script references to Silverlight.js (the standard silvelight 1.0 file), Page.Xaml.Js - which is where I have the code listed above, and what I have called master.js which has the standard createSilverlight method in it. This is the code that gets generated for you by Blend or VS2008. I also have a service reference to the BannerImages.asmx web service detailed above:
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Scripts>
<asp:ScriptReference Path="~/js/master.js" />
<asp:ScriptReference Path="~/js/Page.xaml.js" />
<asp:ScriptReference Path="~/js/Silverlight.js" />
</Scripts>
<Services>
<asp:ServiceReference Path="~/WebServices/BannerImages.asmx" />
</Services>
</asp:ScriptManager>
All that is left to do now is to host the Silverlight control on the page somewhere:
<div id="silverlightControlHost" style="float:right;
height: 300px; width: 300px;">
<script type="text/javascript">createSilverlight();</script>
</div>
Hope this helps someone!
Cheers
Ian