![]() |
Web Development »
Silverlight »
Controls
Beginner
License: The Code Project Open License (CPOL)
Silverlight integrated into ASP.NET Ajax Control (Fifteen Puzzle Game)By Ferreri Gabriele (Megasoft78)Silverlight integrated into ASP.NET Ajax Control (Fifteen Puzzle Game) |
C# (C# 2.0), Javascript, XML, CSS, HTML, XHTML, .NET (.NET 2.0), ASP.NET, Visual Studio (VS2005), XAML, WebForms, Ajax, Dev
|
||||||||||
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||

Recently, I'm interested in a very amazing technology called Silverlight, and I'm trying to learn it because it's very powerful.
Actually Silverlight have 2 versions:
Silverlight 1.0 release
Silverlight 2.0 beta1
Unfortunately, to easily use Silverlight 2.0 beta1 is necessary Framework 3.5 and Visual Studio 2008 personal or above.
My idea is to integrate a Silverlight control into an ASP.NET Ajax control, but it's seem quite difficult without Visual Studio 2008. For this reason I integrated a Silverlight 1.0 control into ASP.NET Ajax control using Visual Studio 2005.
Normally when I start to learn a new technology I always try to implement a very simple example, but to make all more interesting, normally I implement a complete application or game.
When I was a child and there were no computers at home, I spent a bit of my free time playing with a game called Fifteen Puzzle. It's a very simple game but not absolutely easy to solve at the begin.
More details about it at this link
Then, I implemented it in Silverlight 1.0 integrated into a ASP.NET Ajax control.
The solution is divided in the following projects:
In the web application we have just a ASP.NET web form that contains the control and a ScriptManager (the core of ASP.NET Ajax Framework).
In the control we have the following files:
The class FifteenPuzzle extends ScriptControl (base class for all ASP.NET Ajax control on server side) and override 2 method:
protected override IEnumerable<ScriptDescriptor> GetScriptDescriptors()
{
ScriptControlDescriptor descriptor = new ScriptControlDescriptor("Controls.FifteenPuzzle", this.ClientID);
descriptor.AddProperty("xamlUrl", this.Page.ClientScript.GetWebResourceUrl(this.GetType(), "Controls.Resources.FifteenPuzzle.xaml"));
descriptor.AddProperty("width", this.Width.ToString());
descriptor.AddProperty("height", this.Height.ToString());
descriptor.AddProperty("imageUrl", this.ImageUrl);
descriptor.AddProperty("puzzleRenderMode", this.PuzzleRenderMode);
yield return descriptor;
}
protected override IEnumerable<ScriptReference> GetScriptReferences()
{
List<ScriptReference> scripts = new List<ScriptReference>();
ScriptReference scriptReference1 = new ScriptReference();
scriptReference1.Path = this.Page.ClientScript.GetWebResourceUrl(this.GetType(), "Controls.Resources.FifteenPuzzle.js");
scripts.Add(scriptReference1);
ScriptReference scriptReference2 = new ScriptReference();
scriptReference2.Path = this.Page.ClientScript.GetWebResourceUrl(this.GetType(), "Controls.Resources.Helper.js");
scripts.Add(scriptReference2);
ScriptReference scriptReference3 = new ScriptReference();
scriptReference3.Path = this.Page.ClientScript.GetWebResourceUrl(this.GetType(), "Controls.Resources.Silverlight.js");
scripts.Add(scriptReference3);
return scripts;
}
The file Controls.Resources.FifteenPuzzle.js contains the javascript class Controls.FifteenPuzzle the encapsulate most of the logic.
The position of each piece of puzzle is contained into a multiple array 4x4. At the begin the array is initialized to the normal order and using javascript I render the pieces dynamically.
When the puzzleRenderMode is set to Number the following is the xaml generated for each piece:
<Canvas Name="FifteenPuzzle1_Cell_15" Canvas.Left="219" Canvas.Top="370"
Canvas.ZIndex="3" Width="100" Height="100" Background="White" Cursor="Hand">
<Rectangle Fill="#80000000" Width="98" Height="98" Canvas.Top="2" Canvas.Left="2" RadiusX="15" RadiusY="15">
</Rectangle>
<Rectangle Width="100" Height="100" Canvas.Top="0" Canvas.Left="0" RadiusX="15" RadiusY="15">
<Rectangle.Fill><LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="Green"/>
<GradientStop Offset="0.6" Color="Lime"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle><Rectangle Width="98" Height="98" Canvas.Top="1" Canvas.Left="1" RadiusX="14" RadiusY="14">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="#FFFFFFFF"/>
<GradientStop Offset="1" Color="#00000000"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<TextBlock Name="FifteenPuzzle1_TextBlock_3_2" Canvas.Left="0" Canvas.Top="5"
Canvas.ZIndex="1" FontFamily="Verdana" FontSize="70" Text="15" FontWeight="Bold" Cursor="Hand" />
</Canvas>
When the puzzleRenderMode is set to Image the following is the xaml generated for each piece:
<Image Name="FifteenPuzzle1_Cell_15" Canvas.Left="19" Canvas.Top="70"
Canvas.ZIndex="3" Width="400" Height="400" Cursor="Hand" Source="Resources/Photo.jpg">
<Image.Clip>
<RectangleGeometry Rect="200,300,100,100" RadiusX="15" RadiusY="15">
</RectangleGeometry>
</Image.Clip>
<Image.RenderTransform>
<TranslateTransform Name="FifteenPuzzle1_Cell_15_Transform" X="0" Y="0" />
</Image.RenderTransform>
</Image>
The algorithm used to shuffle the pieces is very easy and probably not really optimized, but seem work fine. I just create a random number between 1 and 15 and try if the move is available. The problem with this algorithm is that in theory it could take long time but for the "Law of large numbers" work fine. :)
The most important part of javascript class is the integration with Silverlight.
In the _renderControl function is called the Silverlight.createObject that instantiate the plugin attached to one html div. When the plugin is instantiated the event handler _onXamlLoaded is called and the dynamic part of xaml is rendered.
_renderControl : function()
{
this.get_element().innerHTML = String.format("<div id='{0}_Content' style='width:{1};height:{2}'></div>",
this.get_id(), this.get_width(), this.get_height());
var hostId = String.format("{0}_Host", this.get_id());
var bounds = Sys.UI.DomElement.getBounds(this._getContentElement());
Silverlight.createObject(this.get_xamlUrl(), this._getContentElement(), hostId,
{ width:bounds.width.toString(), height:bounds.height.toString(), version:'1.0' },
{ onError:null, onLoad:Function.createDelegate(this, this._onXamlLoaded) },
null);
},
_onXamlLoaded : function(plugIn, userContext, rootElement)
{
this._plugIn = plugIn;
this._rootElement = rootElement;
this._renderNumbers();
this._drawShuffleButton();
},
I stored the references to plugin and rootElement in local javascript variable because I use it to generate dynamically the xaml using createFromXaml method. Infact when I generate the pieces I used the following code to attach it to the static part of xaml var numberElement = this._plugIn.content.createFromXaml(sb.toString(), false);
this._rootElement.children.add(numberElement);
and the following code to get the element using the name and to attach the event handler on mouse click:
var elementNumber = this._rootElement.findName(String.format("{0}_Cell_{1}", this.get_id(), n));
elementNumber.AddEventListener("MouseLeftButtonDown", this._onNumberClick)
I know that this is a very poor example compared with the possibility available with this framework, but it can be useful to start to understand the technology and to understand the possibility to integrate it into an existing ASP.NET application.
| You must Sign In to use this message board. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 17 Jun 2008 Editor: |
Copyright 2008 by Ferreri Gabriele (Megasoft78) Everything else Copyright © CodeProject, 1999-2009 Web16 | Advertise on the Code Project |